17

在存储库代码中,在另一个团队开发的模块中,我发现价格可以从美分转换为欧元,只需将数字除以100。

代码是Javascript格式的,因此它使用IEEE 754标准标准。

我知道将货币值作为浮点数处理是不安全的,但在将任务发送给其他团队之前,我想知道这种情况是否安全。

到目前为止,我没有发现任何整数除以100的结果不准确的情况。让我们更进一步:100只是2*2*5*5.

我们知道数字除以2是安全的,因为它只是一个位置的转换。

所以我们可以很容易地说,如果存在一个不能被5精确整除的数字,那么被100整除是不准确的。

我做了很多测试,没有找到任何这些数字,但我还远远没有对论文进行理论论证。

那么,在IEEE 754标准中,数字除以100安全吗?

8
  • 6
    不-我想这不是数学交流的问题,这完全就在这里 评论 2019年3月12日17:38
  • 2
    你的应用程序只处理整分钱吗?不是分数分吗?(许多金融应用程序的交易价格都是零星的。) 评论 2019年3月12日17:39
  • 1
    @T。J·克劳德(J.Crowder):我知道这是经验:)但我仍然希望能听到被投下的选民的评论,也许可以从我的错误中吸取教训——如果有的话 评论 2019年3月12日17:39
  • 1
    最少的相关:stackoverflow.com/questions/54903883/…我可以发誓这件事已经被掩盖了,但我没有找到它(除了那个问题)。 评论 2019年3月12日17:41
  • 2
    关于“我没有发现整数除以100得到不准确的结果”:在大多数情况下,除以100必然得到不实际的结果,因为没有一个有理数的除数以最简单的形式包括5或25,在二进制浮点中是可以表示的。例如,1/100产生0.0100000000000020816681711721685132943093776702880859375。这种差异是否重要取决于如何处理这个数字。 评论 2019年3月12日18:38

2个答案2

重置为默认值
10

具有15个有效精度数字的浮点十进制数转换为64位二进制浮点数(编号在JavaScript中)并返回到十进制,而不会丢失精度。虽然二进制数可能无法准确存储十进制数,但它具有更多的精度位(最少需要17个十进制有效数字来表示53位的尾数),并通过精确取整转换为原始十进制数。尾数的这些额外二进制数字正是为了在CPU运算的所有结果中保持这15个有效十进制数字的精确性。请参阅往返转换所需的位数了解详细信息。

当被100除时,二进制结果仍有53位精度,最小精度单位(尾数的最低位)可能有错误,除非结果下溢到0(请参阅每个计算机科学家都应该了解浮点运算详细信息。)。该二进制数仍然可以通过四舍五入转换为精度在15位有效小数内的正确精确十进制数。

换句话说,如果您的十进制数字的有效位数不超过15位,那么将它们除以100可以保持该精度。

例如,尝试123456789012345/1000.000123456789012345 / 100在浏览器控制台中(这两个数字都有15个有效的十进制精度数字),这些除法返回15个有效十进制数字内的正确十进制数字:

123456789012345/1001234567890123.450.000123456789012345 / 1000.00000123456789012345
0
5

如果x个是15位十进制整数,然后进行转换x个到JavaScript编号,除以100,然后将结果转换为具有15个有效十进制数字的数字,即可精确生成x个/100.证据如下。

笔记:

  • 将除法结果转换为具有15位有效十进制数字的数字,可以得到精确的结果x个/100.除法的实际结果,当它位于编号格式,通常不会x个/例如,73/100产生0.729999999999999982236431605997495353221893310546875。
  • 将除法结果转换为更多超过15位有效小数通常也不会产生x个/100,因为额外的数字可能会显示差异,如上面的.73所示。(当然,使用较少的数字可能不足以表示x个/100.)因此,如果希望准确沟通x个/100到另一个进程,则必须精确到15个有效十进制数字(或其他一些错误缓解措施)。
  • 下面的证明适用于15位整数x个,不适用于其他15位有效小数(例如15位十进制数字后跟一个或多个零的数字,或以小数点开头的数字,后跟一些零,然后是15位有效数字)。

前期工作

JavaScript是ECMAScript的实现,在埃克玛-262和ISO/IEC 16262。在第6.1.6条中,Ecma-262规定IEEE-754基本64位二进制浮点格式用于ECMAScript编号类型,但只使用单个NaN。第6.1.6条进一步描述了所使用的算法,该算法本质上是IEEE-754算法,具有四舍五入、ties-to-even。

IEEE-754基本64位二进制浮点格式使用53位有效位。

二进制浮点数的最小精度单位(ULP)是指赋予其有效位中最低有效位位置的值。(因此,ULP按指数缩放。)以ULP度量,所有正常的53位有效位都在[2]中52ULP,2个53ULP)。

对于15位有效的十进制数,其ULP将是归因于15位位置的值第个从前导有效数字开始倒数的数字位置。

引理

首先,我们确定了一个众所周知的事实,即将一个15位有效的小数转换为编号如果数字在编号格式。

如果x个是浮点格式(2)正常范围内的15个有效十进制数字(不一定是整数)−1022≤ |x个| < 21024),然后转换x个将结果转换为浮点格式中可表示的最接近的值,然后将结果转换成15位有效的十进制数字x个,当两个转换都是以四舍五入到最近、ties-to-even的方式执行时。为了看到这一点,让我们是第一次转换的结果。如果不同于x个小于ULP的½x个,然后x个是最接近的15位有效数字因此必须是第二次转换的结果。

在第一次转换中,结果距离最多为½ULPx个,由于舍入规则。这是一个至多½/2的相对精度52(即潜在的½ULP误差除以可用ULP测量的最小有效位)。因此,不同于x个最多2分之一53在最坏的情况下x个可以是9999999999999=1015−1,因此相对于ULP的误差x个将是(1015−1)/253,约为ULP的.111倍x个因此,总是不同于x个小于其ULP的½,因此转换返回到15位有效的十进制数字会产生x个.

证明

如果x个是一个15位小数的整数,它在编号格式,因为编号格式的有效位为53位,因此能够精确表示最多为2的所有整数53,约9.007e15,大于1015.

因此,转换x个编号产量准确x个没有错误。

然后,根据算术结果的舍入规则x个以100表示最接近的数字x个/100.叫这个现在请注意x个/100是一个可以用15位有效小数表示的数字。(它可以用科学记数法写成x个•10−2或在源代码中作为的数字x个后缀为电子2.)注意转换x个/100至编号也会产生收益,因为转换产生的数字与除法一样,在编号最接近的格式x个/100.通过引理,转换的结果x个/100至编号并返回到15个有效的小数位数x个/100,因此转换的结果x个编号,然后除以100,再转换为15个有效的十进制数字也会得到x个/100.

0

您的答案

单击“发布您的答案”,表示您同意我们的服务条款并确认您已阅读我们的隐私政策.

不是你想要的答案吗?浏览标记的其他问题问你自己的问题.