【问题标题】:How a Double.ToString() displays more chars that Double's precision? [closed]Double.ToString() 如何显示比 Double 精度更高的字符? [关闭]
【发布时间】:2012-10-19 17:05:02
【问题描述】:
?(1.0-0.9-0.1)
-0.000000000000000027755575615628914

?((double)1.0-(double)0.9-(double)0.1)
-0.000000000000000027755575615628914

?((double)1.0-(double)0.9-(double)0.1).GetType()
{Name = "Double" FullName = "System.Double"}

?((double)1.0-(double)0.9-(double)0.1).ToString()
"-2,77555756156289E-17"

Double.ToString() 如何显示比double 的精度(15-16) 更多的字符(32)?

我希望 MyObject.ToString() 代表 只是 MyObject 而不是 MyObject+SomeTrashFromComputer

为什么

?0.1
0.1
?0.2-0.1
0.1
?0.1-0.1
0.0

但是

?1.0-0.9-0.1
-0.000000000000000027755575615628914

为什么

?1.0-0.1-0.9
0.0

但是

?1.0-0.9-0.1
-0.000000000000000027755575615628914

【问题讨论】:

  • 实际上你的 ToString() 结果有更少的(有效的)数字。而且它的字符肯定更少,大约一半。
  • 您将精度与有效数字 (en.wikipedia.org/wiki/Significant_figures) 混淆了,您应该知道像 0.1 这样的小数不能精确地用二进制表示。您是否尝试过使用 Decimal 数据类型?
  • 精度不准确,如果你不想要“垃圾”,不要使用Double,或者开始四舍五入。
  • @HenkHolterman 我认为“一些来自计算机的垃圾”表明他不知道浮点错误,而不是不知道科学记数法。
  • @Servy - 但不确定/不清楚,我关闭的主要原因。

标签: c# .net vb.net double floating-point-precision


【解决方案1】:

Double.ToString() 如何显示比 double 的精度 (15-16) 更多的字符 (32)?

不是显示 32,而是显示 17,前导零不算。 浮点点意味着它可以单独跟踪大小的变化和值的变化。

我希望 MyObject.ToString() 只代表 MyObject

确实如此,由于浮点数的机制,可能会略有不同,但真正的数字是由字符串精确表示的。

不是 MyObject+SomeTrashFromComputer

没有垃圾,有浮点不准确。它也以十进制形式存在,将1/3 准确地记为十进制数。你不能,它涉及重复的小数位。双精度数以 2 为基数存储,因此即使 0.1 也会创建一个重复的“十进制”。

还请注意,您将获得两种不同的表示形式,因为您调用了两种不同的显示方法。 ToString 具有特定的语义,而您的调试窗口可能有不同的语义。如果您想知道E 的含义,也请查阅科学记数法。

【讨论】:

  • 我知道“1/3”不准确,因为有偏差,但我无法理解为什么“0.1”不准确!!!?
  • @serhio Double 以二进制而非十进制工作。尝试用二进制写 0.1(十进制)。你会得到 0.0001100110011001100110011001100110011...
  • 为什么 0.2-0.1 总是正好 0.1??
  • 为什么 1.0-0.1-0.9 完全是 0.0 而不是 1.0-0.9-0.1??
  • @serhio 0.2-0.1 并不完全给出0.1,它只是在显示给您时产生一个四舍五入为0.1 的数字,因为这是最接近的近似值。 why 1.0-0.1-0.9 is EXACTLY 0.0 but not 1.0-0.9-0.1? 第一个实际上并没有完全正确,它只是“巧合地”四舍五入到正确的值。这两个表达式都会导致浮点错误。
【解决方案2】:

查看System.Double

请记住,浮点数只能逼近十进制数,并且浮点数的精度决定了该数字逼近十进制数的精度。默认情况下,Double 值包含 15 个十进制数字的精度,尽管内部维护最多 17 位。浮点数的精度有几个后果:

在特定精度下看起来相等的两个浮点数可能不相等,因为它们的最低有效数字不同。

如果使用十进制数,使用浮点数的数学或比较运算可能不会产生相同的结果,因为浮点数可能与十进制数不完全近似。

如果涉及浮点数,则值可能不会往返。如果一个操作将原始浮点数转换为另一种形式,则称一个值往返,逆运算将转换后的形式转换回浮点数,并且最终的浮点数等于原始浮点数数字。往返可能会失败,因为在转换中丢失或更改了一个或多个最低有效数字。

【讨论】:

  • 为什么“0.1”不仅仅是“0.1”而是“0.1000000000000000xyzrklsjdhf”?
【解决方案3】:

我认为您不清楚浮点数的两个方面; 精度范围

浮点表示的精度是它可以接近给定小数的程度。 double 的精度为 15-16 位。

浮点表示的范围与该表示可以近似的数字的大小有关。 double 的范围是 +/-5.0e-324 到 +/-1.7e308。

因此,在您的情况下,计算精确到 16 个字符,之后就不是预期的那样了。

Some numbers 看起来很简单,但在标准浮点表示中是无法表示的。如果你要求绝对没有偏差,你应该使用不同的数据类型,比如decimal

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多