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

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

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

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

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

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

无法用二进制浮点数精确表示的数字的简单示例包括1/3 2/3 1/5 1/3 2/3 1/5

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

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

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

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

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

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

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

浮点在下面的公式中表示为sem

 s * m * 2^e 

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

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

作为示例, 02^53 - 1之间的所有数字可以表示为乘以2^0 = 1 。 而且你也可以用2除以( .5分数)代表所有这些数字。 等等。

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