为什么1.0f+0.0000000171785715f返回1f?
-
22-08-2019 - |
题
一小时后试图找到一个错误,在我的代码中我终于找到原因。我想添加一个非常小的浮到1f,但没有被发生的事情。同时,试图找出为什么我发现,加入该小浮到0f完美工作。
为什么会这样?不会这样做'数量级'?是否有任何解决办法这个问题?
在此先感谢。
编辑:
改变给双精密或小数不是一个选项的时刻。
解决方案
因为精确度为一个单一的精度(32bit)浮点值大约是7位数字后的小数点。这意味着你的价值正在增加基本为零,至少当加入 1
.值本身,但是,可以毫不费力地储存在一个浮起来的指数是小型的,在这种情况。但是,要成功地将它添加到 1
你必须使用该指数的数量较大...然后后面的数字零消失在四舍五入。
你可以使用 double
如果你需要更多的精确度。绩效明智的,这不应该使一个差异在今天的硬件和记忆往往也不作为约束的,你要想想每一个变量。
编辑: 正如你指出,使用 double
不是一个选择你可以使用 嘉饭求和, 如 akuhn 指出在评论。
另一个选项可以执行的中介的计算,在双精密度和随后转换为 float
再次。这只会有帮助,然而,当有几个业务不仅仅是添加一个非常小的数目较大的一个。
其他提示
这大概是因为的精度位数在浮法数量是恒定的,但指数可明显变化。
这意味着,虽然你可以在你的小号码添加为0,你不能指望将其添加为一个数字,有一个指数从0不同,因为那里只是不会精确左侧的数字不足。
您应该阅读什么每台计算机科学家应该知道关于浮点运算
它看起来有事情做与浮点精度。如果我是你,我会使用一个不同的类型,比如decimal
。这应该修复精度误差。
通过float
,你只能得到大约7位数的的准确性。所以,你的number'll四舍五入到1楼。如果你想存储这样的数字,使用double
代替
除接受的答案:如果您需要总结许多小号码和一些较大的,你应该使用的 Kahan的求和
如果性能是一个问题(因为你不能使用double
),然后二进制比例/固定翼点可能是一种选择。 float
s存储为整数,但由大量(比如,2 ^ 16)缩放。中间运算与(相对快)整数操作完成。最终的答案可以在端被转换回浮点,通过以该比例因子除以。
如果目标处理器缺乏硬件浮点单元这通常完成的。
您正在使用你的文字,这将使得这些花车代替双打的F后缀。所以你很小的持股量将在更大的浮动消失。