Double.ToString() 何时以科学计数法返回值?

Posted

技术标签:

【中文标题】Double.ToString() 何时以科学计数法返回值?【英文标题】:When does Double.ToString() return a value in scientific notation? 【发布时间】:2012-10-19 15:40:02 【问题描述】:

我认为这与前导零或尾随零的数量有关,但我在 msdn 中找不到任何可以给我具体答案的内容。

Double.ToString(CultureInfo.InvariantCulture) 什么时候开始以科学计数法返回值?

【问题讨论】:

【参考方案1】:

来自Double.ToString(IFormatProvider) 的文档:

此实例使用通用数字格式说明符 ("G") 进行格式化。

来自General Numeric Format Specifier 的文档:

如果用科学计数法表示数字所产生的指数大于 -5 且小于精度说明符,则使用定点表示法;否则,使用科学计数法。如果需要,结果包含一个小数点,小数点后的尾随零被省略。如果存在精度说明符并且结果中的有效位数超过指定的精度,则通过舍入去除多余的尾随数字。

但是,如果数字是 Decimal 并且省略了精度说明符,则始终使用定点表示法并保留尾随零。

Double 的默认精度说明符记录为 15。

虽然在表格前面,但措辞略有不同:

结果:定点或科学记数法中最紧凑的。

我还没有弄清楚这两个是否总是等同于 Double 值...

编辑:根据亚伯的评论:

此外,它并不总是最紧凑的符号。 0.0001 大于 1E-04,但第一个是输出。此处的 MS 文档不完整。

当然,这符合更详细的描述。 (因为所需的指数大于 -5 且小于 15。)

【讨论】:

您的回答不包括精度说明符是什么,这也是它按原样显示的部分原因。默认值为15。此外,它并不总是最紧凑的符号。 0.00011E-04 大,但第一个是输出。此处的 MS 文档不完整。 我不同意“最紧凑”一词,并认为 msdn 文档在这方面具有误导性。如果你取 double x=13950,那么 G4 格式会产生“1.395E+04”,这与“最紧凑”相差甚远。在我看来,“G”格式在 C、Fortran 等中效果更好,它真正产生了“最紧凑”的字符串。 C# 迫使我寻找解决方法...【参考方案2】:

从文档中可以看出,将选择最紧凑的形式来表示数字。

即,当您不指定格式字符串时,default is the "G" format string。来自specification of the G format string 如下:

结果:定点或科学记数法中最紧凑的一种。

default for the number of digits 是带说明符的 15。这意味着一个可以完全表示为某个二进制表示形式的数字(如 hariyott 示例中的 0.1)将显示为定点,除非指数表示法更紧凑。

当有更多数字时,默认情况下会显示所有这些数字(最多 15 个),并在较短的时候选择指数表示法。

把这些放在一起:

?(1.0/7.0).ToString()
"0,142857142857143"      // 15 digits
?(10000000000.0/7.0).ToString()
"1428571428,57143"       // 15 significant digits, E-notation not shorter
?(100000000000000000.0/7.0).ToString()
"1,42857142857143E+16"   // 15 sign. digits, above range for non-E-notation (15)
?(0.001/7.0).ToString()
"0,000142857142857143"   // non E-notation is shorter
?(0.0001/7.0).ToString()
"1,42857142857143E-05"   // E-notation shorter

而且,有趣的是:

?(1.0/2.0).ToString()  
"0,5"                    // exact representation
?(1.0/5.0).ToString()
"0,2"                    // rounded, zeroes removed
?(1.0/2.0).ToString("G20")
"0,5"                    // exact representation
?(1.0/5.0).ToString("G20")
"0,20000000000000001"    // unrounded

这是为了展示幕后发生的事情,以及为什么0.2 写成0.2,而不是0,20000000000000001,实际上是这样。默认情况下,显示 15 位有效数字。当有更多数字时(并且总是有,除了某些特殊数字),这些数字按正常方式四舍五入。舍入后,去除多余的零。

请注意,double 的精度为 15 位或 16 位,具体取决于数字。因此,通过显示 15 位数字,您看到的是正确舍入的数字,并且始终是完整的表示,并且是双精度的最短表示

【讨论】:

【参考方案3】:

它使用格式化程序“G”(表示“General”),指定使用“最紧凑的定点或科学记数法”http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx

因此,由于定点 0.00001 的字符数比 1E-05 多,因此将有利于科学计数法。我想如果它们的长度相等,那么它有利于定点。

【讨论】:

0.0001 的字符数比 1E-04 多,但首选... ;)【参考方案4】:

我刚刚用循环尝试了这个:

double a = 1;
for (var i = 1; i < 10; i++)

    a = a / 10;
    Console.WriteLine(a.ToString(CultureInfo.InvariantCulture));

输出是:

0.1
0.01
0.001
0.0001
1E-05
1E-06
1E-07
1E-08
1E-09

【讨论】:

我尝试了类似的实验,但仍然没有准确的答案来解释为什么会发生转换。

以上是关于Double.ToString() 何时以科学计数法返回值?的主要内容,如果未能解决你的问题,请参考以下文章

Double ToString() 没有科学记数法,不返回 0.0 的字符串

将非常小的双精度值转换为字符串(使用科学计数法)(Java)

如果分数不能以二进制精确表示,Double.toString() 如何工作?

如何使java中double类型不以科学计数法表示

Java导出csv数字如何不以科学计数显示,不能改变原来的值

如何使java中double类型不以科学计数法表示