双打在什么时候开始失去准确性

At what point do doubles begin to lose precision?

本文关键字:失去 准确性 开始 什么时候      更新时间:2023-10-16

我的应用程序需要对一些数字执行一些操作:><==!=+-++等(但不进行除法)。这些数字有时是整数,很少是浮点数。

如果我在内部使用"double"类型(由IEEE 754定义),即使是整数,直到什么时候我才能安全地将它们用作int,而不会出现奇怪的舍入错误(例如,n == 5 && n == 6都为真,因为它们舍入到相同的数字)?

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

作为一个额外的答案,同样的问题,但适用于float

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

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

如果您只想保存整数值,那么通常有一种64位整数类型比双精度更合适。

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

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

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

decimaldouble的主要区别在于decimal是定点,double是浮点。这意味着十进制存储一个精确的值,而double表示由分数表示的值,并且精度较低。decimal是128位,因此它需要双倍的存储空间。decimal的计算速度也较慢(测量!)。

如果您需要更大的精度,那么BigInteger可以从.NET4中使用。(您需要自己处理小数点)。这里你应该知道,BigInteger是不可变的,所以对它的任何算术运算都会创建一个新的实例——如果数字很大,这可能是为了性能而抄袭。

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