6

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

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

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

4

4 回答 4

7

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

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

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

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

于 2012-08-28T18:37:50.440 回答
3

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

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

于 2012-08-28T18:29:36.550 回答
1

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

考虑使用双精度数,小数点左侧(从 0 开始的索引 I)的每个数字 N 表示值 N * 2^I,小数点右侧的每个数字表示值 N * 2^( -一世)。

例如,5.625(以 10 为底)将是 101.101(以 2 为底)。

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

于 2012-08-28T18:26:47.557 回答
1

浮点数表示为se并且m在以下公式中

s * m * 2^e

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

基本上,您可以表示介于2 的某个幂(可能是负幂)之间0并乘以它们的所有数字。2^53 - 1

例如,0和之间的所有数字2^53 - 1都可以乘以 来表示2^0 = 1。您还可以通过将它们除以2.5带分数)来表示所有这些数字。等等。

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

于 2012-08-28T18:42:19.270 回答