Double数据类型不能正确表示某些十进制值。这是因为浮点数表示实数的方式。这意味着,在表示货币价值时,应使用十进制值类型以防止错误。(请随时更正此前言中的错误)
我想知道在标准.Net框架下(如果有差异,则为C#),在64位体系结构下,哪些值会在Double数据类型下出现此类问题?
我希望得到的答案是一个公式或规则,以查找此类值,但我也希望得到一些示例值。
Double数据类型不能正确表示某些十进制值。这是因为浮点数表示实数的方式。这意味着,在表示货币价值时,应使用十进制值类型以防止错误。(请随时更正此前言中的错误)
我想知道在标准.Net框架下(如果有差异,则为C#),在64位体系结构下,哪些值会在Double数据类型下出现此类问题?
我希望得到的答案是一个公式或规则,以查找此类值,但我也希望得到一些示例值。
由于浮点数集合(以任何表示方式)是有限的,而实数集合是无限的,因此找到一个不能被浮点数精确表示的实数的算法是随机选择一个实数。这个实数能够被精确表示为浮点数的概率是0
。
10^5000
不能用 double
表示,但它可以被表示为一个二进制浮点数。 - CodesInChaos0
可以被表示为没有任何数字的和, 0
在几乎所有你考虑过的进制下都是 0
。 IEEE 二进制表示法中包括 2 个关于 0
的“值”,一个是 +0
,一个是 -0
。它们的小数部分和指数部分都只有 0
,而 -0
的符号位为 1
。大多数系统会隐藏 0
的符号,不让程序员和用户看到。 - High Performance Markdouble
类型中的数值都可能存在一定的误差。除非你存储的是一个常量值,否则很可能会有一些误差。如果绝不能有任何误差,并且这些值不是常量,那么你可能不应该使用浮点类型。这个问题实际上超越了任何单一的编程语言或平台。不准确性实际上是二进制数据固有的。
考虑到双精度浮点数,每个数字N在小数点左边(从0开始的索引I)表示值N * 2 ^ I,小数点右边的每个数字表示值N * 2 ^(-I)。
例如,5.625(十进制)将是101.101(二进制)。
根据这个计算,对于一个不能被表示为不同I值的2 ^(-I)之和的十进制值,其作为双精度浮点数的值将是不正确的。
浮点数在以下公式中表示为s
、e
和m
s * m * 2^e
这意味着任何不能用给定表达式(在s
、e
和m
的各自域中)表示的数字都无法被准确地表示。
基本上,您可以表示所有介于0
和2^53 - 1
之间的数字乘以某个二的幂次方(可能是负幂次方)。
例如,介于0
和2^53 - 1
之间的所有数字都可以用2^0 = 1
相乘来表示。您还可以通过将它们除以2
(带有.5
分数)来表示所有这些数字。等等。
这个答案并没有完全涵盖这个主题,但我希望它能有所帮助。