考虑以下代码:
0.1 + 0.2 == 0.3 -> false
0.1 + 0.2 -> 0.30000000000000004
为什么会出现这些错误?
二进制浮点数学就是这样。在大多数编程语言中,它基于IEEE754标准。问题的症结在于数字以这种格式表示为整数乘以2的幂。分母不是2的幂的有理数(例如0.1
,是1/10
)无法精确表示。
对于0.1
标准binary64
格式,表示形式可以完全按照
0.1000000000000000055511151231257827021181583404541015625
以十进制表示,或
0x1.999999999999ap-4
以C99十六进制表示法表示。
相比之下,合理数量0.1,这是1/10可以完全按照书面
0.1
以十进制表示,或
0x1.99999999999999...p-4
以C99十六进制表示法的类似形式表示,其中…表示9的无休止序列。
常量0.2和0.3程序中的常量也将接近其真实值。碰巧的是,最近double
以0.2低于合理数量较大0.2但最近double
以0.3
低于合理数量较小0.3
。的总和0.1
和0.2
卷起比有理数较大0.3
,并因此与在代码中不同意恒定。
每个计算机科学家都应该了解浮点算术,这是对浮点算术问题的相当全面的处理。有关更易于理解的说明,请参见float-point-gui.de
。
旁注:所有位置(以N为底的)数字系统均会精确地共享此问题
普通的旧十进制数(以10为底)有相同的问题,这就是为什么像1/3这样的数字最终会变成0.333333333 ...
您偶然发现了一个数字(3/10),该数字很容易用十进制表示,但不适合二进制。它也是双向的(在某种程度上):1/16是一个丑陋的数字,十进制(0.0625),但是在二进制中,它看起来像十进制的10,000十分整洁(0.0001)****-如果我们在习惯在我们的日常生活中使用以2为底的数字系统,您甚至会看到该数字,并且本能地了解到您可以通过将某物减半,一次又一次减半而到达那里。
**当然,这并不完全是将浮点数存储在内存中的方式(它们使用科学计数法的形式)。但是,它确实说明了二进制浮点精度误差趋于增加的观点,因为我们通常感兴趣的“真实世界”数通常是10的幂-但这仅仅是因为我们使用了十进制数天-今天。这也是为什么我们说类似71%而不是“每7个中有5个”(71%是近似值,因为5/7不能用任何十进制数字精确表示)的原因。
否:二进制浮点数没有坏,它们恰好与其他所有base-N数系统一样不完美:)
侧面说明:在编程中使用浮点数
实际上,这种精度问题意味着您需要使用舍入函数将浮点数四舍五入为您想要的任意小数位,然后再显示它们。
您还需要用允许一定程度的容忍的比较替换相等性测试,这意味着:
千万不能做if (x == y) { ... }
反而做if (abs(x - y) < myToleranceValue) { ... }
。
abs绝对值在哪里。myToleranceValue
需要为您的特定应用选择-这与您准备允许多少“摆动空间”以及要比较的最大数字有很大关系(由于精度问题) )。当心所选语言中的“ epsilon”样式常量。这些不得用作公差值。
我阅读关于浮点和舍入在浮点算术期间发生的错误。 我读了很多关于IEEE754单精度/双精度格式的文章。我知道有符号位、8(或)11位指数和23(或)52位有效位以及隐式前导位。 我也知道分母不是质因数2的实数不能完全表示,例如二进制中的0.1是0.0001100110011...... 我知道0.1 0.1 0.1不等于0.3,因为舍入误差的累积。 同样,0.5也可以用二进制格式表示,因为它是1/
几年前,在20世纪90年代初,我创建了图形包,用于优化基于定点算术的计算,并预先计算出了cos、sin和sqrt和log近似的缩放方程的表格,这些表格使用牛顿近似法。这些先进的技术似乎已经成为图形和内置数学处理器的一部分。大约5年前,我上了一堂数值分析课,涉及到一些古老的技术。我已经编码了近30年,很少看到那些老的定点优化在使用,即使在为世界级粒子加速器实验的GPGPU应用工作之后。固定点方法是否
本文向大家介绍DSP中浮点转定点运算--定点数模拟浮点数运算及常见的策略,包括了DSP中浮点转定点运算--定点数模拟浮点数运算及常见的策略的使用技巧和注意事项,需要的朋友参考一下 4.定点数模拟浮点数运算及常见的策略 相信大家到现在已经大致明白了浮点数转换成定点数运算的概貌。其实,原理讲起来很简单,真正应用到实际的项目中,可能会遇到各种各样的问题。具我的经验,常见的策略有如下几条: 1)除法转
对于这些代码行,我得到0作为输出,即它们都是相等的。现在,如果我理解正确,a b和c可能会存储稍微不同版本的真值.3因此,当做一个Float.compare(...)对这些值,我希望得到一个输出值,而不是0。为什么我把它们取为0?
本文向大家介绍DSP中浮点转定点运算--浮点数的存储格式,包括了DSP中浮点转定点运算--浮点数的存储格式的使用技巧和注意事项,需要的朋友参考一下 二:浮点数的存储格式 2.1 IEEE floating point standard 上面我们说了,浮点数的小数点是不固定的,如果每个人都按照自己的爱好存储在电脑里,那不就乱套了吗?那么怎么在计算机中存储这种类型的数字呢?象这类古老的问题前人早都
以下是go中的示例代码: 结果线A1、B1和C1之间的差异是可以理解的。然而,从A2开始到C2魔法来了。来自B2和C2的结果都与来自A2线的结果不匹配。对于x2行(x=A、B或C)也是如此——但是x2和x4的输出是相同的。 为了确保,让我们以二进制形式打印结果。 上面代码中的一些事实(一个在bin表单中): 行A11和C11之间有差异(最后一位数字——就在指数之前)。 行A12和C12几乎相同(除