双精度值无法正确表示哪些值

时间:2012-08-28 18:21:41

标签: c# .net floating-point double decimal

Double数据类型无法正确表示某些基数为10的值。这是因为浮点数代表实数。这意味着当表示货币值时,应该使用十进制值类型来防止错误。 (随意纠正本序言中的错误)

我想知道的是,在标准.Net框架中64位架构下的双数据类型下出现此类问题的值是什么(C#如果有所不同)?

我希望答案是一个公式或规则来找到这样的值,但我也想要一些示例值。

4 个答案:

答案 0 :(得分:7)

任何不能写为2的正负幂之和的数字都不能精确地表示为二进制浮点数。

浮点数的公共IEEE formats for 32位和64位表示形成了进一步的约束;它们限制有效数和指数中的二进制数字的数量。因此,存在最大和最小可表示数字(如果存储器服务,则大约+/- 10 ^ 308(基数-10))并且限制可以表示的数字的精度。这种精度限制意味着,对于64位数字,最大功率2的指数与数字中最小功率之间的差值限制为52,因此,如果您的数字包含2 ^ 52中的项,则可以也包括一个2 ^ -1的术语。

无法在二进制浮点数中精确表示的数字的简单示例包括1/32/31/5

由于浮点数集合(在任何表示中)是有限的,并且实数集合是无限的,因此找到不能完全表示为浮点数的实数的一种算法是选择a实数随机。实数可以精确表示为浮点数的概率为0

答案 1 :(得分:1)

这个问题实际上超越了任何单一的编程语言或平台。这种不准确性实际上是二进制数据所固有的。

考虑到使用double,小数点左边的每个数字N(基于0的索引I)表示值N * 2 ^ I,小数点右边的每个数字表示值N * 2 ^( - I)

例如,5.625(基数10)将是101.101(基数2)。

鉴于此计算,并且对于不同的I值,无法计算为2 ^( - I)之和的十进制值将具有不正确的值作为double。

答案 2 :(得分:1)

您通常需要做好准备,以确保double中存储的任何值都有少量错误。除非你存储一个常量值,否则它可能至少会出现一些错误。如果必须没有任何错误,并且值不是常量,那么您可能不应该使用浮点类型。

在许多情况下,您可能应该问的是,“我如何处理次要浮点错误?”您将想知道哪些类型的操作可能导致大量错误,哪些类型不会导致错误。你需要确保比较“平等”的两个值实际上只是确保它们“足够接近”而不是完全相等,等等。

答案 3 :(得分:1)

浮动在以下公式中表示为sem

s * m * 2^e

这意味着无法使用给定表达式(以及sem的相应域中)无法表示的任何数字都无法准确表示。

基本上,您可以表示02^53 - 1之间的所有数字乘以一定的2的幂(可能是负幂)。

例如,02^53 - 1之间的所有数字都可以用2^0 = 1表示。您还可以将所有这些数字除以2.5分数)。等等。

这个答案并没有完全涵盖这个主题,但我希望它有所帮助。