2013-06-11 65 views
3

我試圖將C#雙值轉換爲指數表示法字符串。考慮這個C#代碼:C#雙重格式化

double d1 = 0.12345678901200021; 
Console.WriteLine(d1.ToString("0.0####################E0")); 
//outputs: 1.23456789012E-1 (expected: 1.2345678901200021E-1) 

誰能告訴我,格式字符串輸出「1.2345678901200021E-1」雙D1,如果可能的話?

+7

'double'沒有那麼高的精度。如果你想保留所有這些數字,你應該使用'decimal'來代替。 –

+2

@JonSkeet據我所知,這正好處於'double'精度的邊緣。因此,「0.12345678901200021 == 0.12345678901200020」,但是「0.12345678901200021!= 0.12345678901200019」和「0.12345678901200021!= 0.12345678901200022」。 – svick

+0

@JonSkeet有趣的是,我正在移植一些Java應用程序,並期望C#能夠打印整個值(如預期的那樣打印Java)。 – danze

回答

3

雙值只能保存15到16位數字,你有17(如果我正確計算的話)。因爲64位雙數只能保存16位數字,所以最後一位數字被截斷,因此當您將數字轉換爲科學記數法時,最後一位數字似乎已被截斷。

您應該使用十進制代替。十進制類型可以保存128位數據,而double只能保存64位。

+1

但是輸出至少省略了兩位數字('21'),而不僅僅是最後一位,就像你聲稱的那樣。 – svick

+0

即使將其更改爲小數? – Robbert

+0

我的意思是在使用'double'的時候。根據你的說法,輸出結果應該是'1.234567890120002E-1',但它實際上是'1.23456789012E-1'。 – svick

1

Console.WriteLine(d1)應該告訴你,double不支持你想要的精度。改爲使用decimal(64bit vs 128bit)。

1

我的直接窗口是說,你可以期望從該double 號碼的最大分辨率是大約 15位數字。

2

the documentation for double.ToString()double沒有精度:

默認情況下,返回值只包含15位精度,儘管最大的17位內部維護。如果此實例的值大於15位,ToString會返回PositiveInfinitySymbol或NegativeInfinitySymbol,而不是預期的數字。如果您需要更高的精度,請使用「G17」格式規範指定格式,該規格始終返回17位精度或「R」,如果數字可以用該精度表示,則返回15位;如果數字只能爲以最大精度表示。

0

我的VS2012即時窗口是說的0.12345678901200021分辨率實際上是16個顯著位數:

0.1234567890120002 

因此我們預計,至少在過去的「2」的數字應在字符串中進行報告。

但是如果你使用了「G17」格式字符串:

0.12345678901200021D.ToString("G17"); 

你將得到與16位精度的字符串。 看到這個answer