提问人:orange0629 提问时间:6/9/2023 更新时间:6/10/2023 访问量:53
在将小数转换为二进制浮点数时,为什么不将小数视为整数
Why not use treat decimals as integers when converting decimals into binary floating points
问:
我知道在将数字转换为二进制时,我们应该区别对待小数点前后的数字,例如,0.625 应该转换为 0.101。对于小数点后的数字,我们继续乘以 2 并得到其整数部分,如下所示:
0.625 * 2 = 1.25 ---- 1
0.25 * 2 = 0.5 ---- 0
0.5 * 2 = 1 ---- 1
但是,这种方法对于像 0.1 这样的数字是不可行的,因为循环是无限的,并且会给出类似 0.0001100110011...,这会导致精度损失。
那么,我们为什么不通过删除小数点来将小数视为整数呢?例如,对于 0.625,我们直接计算 625 的二进制表示,并像浮点类型一样记录指数(这里是 10^-3)。这种方法可以防止在许多情况下失去精度,并且它完美地模拟了人类如何计算小数。
如果原始小数很长,我们可以将其剪切到最大长度,这不会损失太多精度。我真的不知道为什么我们必须使用“多数 2”方法,它会为像 0.1 这样的简单数字引入错误。
我尝试将许多小数转换为二进制,在大多数情况下,我的方法比“乘以 2”方法效果更好。请告诉我我在这个过程中遗漏了什么。
请告诉我为什么我错了。谢谢!
答:
您提出的称为 10 次方比例因子的定点。它是可行的,也用于防止舍入错误(例如用于货币计算)
但是,使用普通的二进制表示(或具有定点的 2 缩放的幂)更快、更方便(即使从硬件的角度来看),因为它简化了许多操作(*、/、pow、log、exp,...)
同样,十进制基数也会出现同样的舍入问题,只需尝试用十进制编写即可......它也永无止境的数字系列......1/3
1/3 = 0.33333333333333333333333333...
但是,这种方法对于像 0.1 这样的数字是不可行的,因为循环是无限的,并且会给出类似 0.0001100110011...,这会导致精度损失。
从数学上讲,它是无限的,但使用二进制浮点编码的 0.1 是不可能的。相反,我们寻找一个附近的值,如 或 。在大约 53 个有效二进制数字之后,我们只需要再多几个来检测四舍五入需求。 0.10000000000000000555...
0x1.999999999999ap-4
请注意,十进制文本(* 2)的加倍可能需要 100 个十进制数字。
如果原始小数很长,我们可以将其剪切到最大长度,这不会损失太多精度。
取决于你是想要一个好的答案还是最好的答案。
考虑典型的最小可编码浮点值,其作为小数的确切值约为 ~750 个有效十进制数字。4.9406564584124654e-324
现在考虑下一个较大的浮点值,同样是 ~750 个有效十进制数字。
将其视为介于这两者之间的文本。
将 附近的值视为略大或稍小的十进制文本(但前 750 位有效十进制数字相同)。要将其转换为最佳浮点值,需要最大长度为 ~750 位数字,这样您就不会失去精度并正确向上或向下舍入。x
x
您的切割要求是超过 750 位数字,以便始终获得最佳答案。
最后,真正好的十进制文本到浮点数都是用宽整数数学完成的。
评论