在什么时候双打开始失去精确度?

时间:2012-02-13 16:29:28

标签: c++ floating-point ieee-754

我的应用程序需要在某些数字上执行某些操作:>,<,==,!=,+, - ,++等(但没有除法)。这些数字有时是整数,更少有浮点数。

如果我在内部使用“double”类型(由IEEE 754定义),即使对于整数,直到我可以安全地使用它们就好像它们是int s一样,而不是在奇怪的舍入中运行错误(例如,n == 5&& n == 6都是真的,因为它们会转到相同的数字)?

显然,各种操作的第二个输入(+, - 等)总是一个整数,我知道用0.000 [..] 01我从开始就会遇到麻烦。

作为奖励答案,同样的问题,但float

2 个答案:

答案 0 :(得分:8)

IEEE-754双尾数中的位数为52,并且有一个额外的隐含位始终为1.这意味着可以精确包含的最大值是2 ^ 53,或9007199254740992。

浮点尾数是23位,同样带有隐含位。可以精确表示的最大整数是2 ^ 24或16777216。

如果你的意图只是保持整数值,那么通常会有一个64位整数类型,它比双精度更合适。

编辑:最初我有2 ^ 53-1和2 ^ 24-1,但我意识到没有必要减去1 - 偶数可以利用尾数右边隐含的0位。

答案 1 :(得分:0)

C#参考: 但是,请注意小数类型的范围小于double。这是双倍可以保持更大的值,但它会失去精度。或者,如MSDN所述:

  

decimal关键字表示128位   数据类型。与浮点相比   类型,十进制类型有更大   精度和较小的范围,其中   使它适合金融和   货币计算。近似的   小数的范围和精度   类型如下表所示。

decimaldouble之间的主要区别在于decimal is fixed-point and double is floating point。这意味着十进制存储精确值,而double表示由分数表示的值,并且不太精确。 decimal是128位,因此需要存储双倍空间。 decimal上的计算也较慢(测量!)。

如果您需要更高的精度,则可以在.NET 4中使用BigInteger。(您需要自己处理小数点)。在这里你应该知道,BigInteger是不可变的,因此对它的任何算术运算都会创建一个新实例 - 如果数字很大,这可能会影响性能。

我建议你仔细研究一下你需要多少精确度。也许你的算法可以使用规范化的值,可以更小?如果性能是一个问题,其中一个内置浮点类型可能会更快。

相关问题