2016-11-14 75 views
1

我有一箇舊的VBA應用程序,它生成的值如1.123456789123456789123456789E-28。當我使用C#搜索等價數據類型時,我在SO Difference between decimal, float and double in .NET?中發現了這篇文章。根據這篇文章的建議,十進制數據類型在C#中具有最大的大小。所以我使用了十進制數據類型,但我發現小數似乎限制了VBA以指數形式表示的大值。所以我再次搜索了一下,發現這篇文章https://msdn.microsoft.com/en-us/library/ae55hdtk.aspx。正如本文中所述,相當於VBA指數形式的C#數據類型

非整數數量的值可以表示爲mmmEeee,其中mmm是 尾數(所述顯著位數)和電氣和電子設備的指數(一個功率的10 )。非整數類型的最高正值分別爲 7.9228162514264337593543950335E + 28(十進制),3.4028235E + 38(單倍)和1.79769313486231570E + 308(雙倍)。

這意味着Double數據類型具有最大的值範圍。所以現在我很困惑十進制和雙精度。

然後我做一個小實驗用代碼象下面

double dbl = 1.123456789123456789123456789E-28; 
    decimal dcl = 1.123456789123456789123456789E-28M; 
    MessageBox.Show(dbl.ToString()); 
    MessageBox.Show(dcl.ToString()); 

的DBL打印值,因爲它是1.123456789123456789123456789E-28而DCL值變爲0.0000000000000000000000000001; 有人可以解釋這裏發生了什麼嗎?什麼是C#中的等效數據類型來表示像VBA中一樣精確的大指數值?

+2

我想如果你進一步閱讀第一篇文章,你會明白不同之處以及何時使用它們。我想你可能誤解了你發佈的第一個鏈接。 – Hank

回答

4

根據C#語言規範:https://msdn.microsoft.com/en-us/library/aa691085%28v=vs.71%29.aspx

  • 的實數被F後綴或f是float類型。例如,文字1f,1.5f,1e10f和123.456F都是浮點類型。
  • D或d後綴的實數字面值是double類型的。例如,文字1d,1.5d,1e10d和123.456D都是double類型。
  • 以M或m爲後綴的實數字面值爲十進制類型。例如,文字1m,1.5m,1e10m和123.456M都是十進制類型。 通過採用準確的 值將此文字轉換爲十進制值,如有必要,使用銀行家的四捨五入將四捨五入爲最接近的可表示值 (第4.1.7節)。 文字中明顯的任何比例都將保留,除非值被舍入或值爲零 (後者情況下符號和比例將爲0)。因此,文字2.900米將被解析爲帶符號0的小數點, 係數2900和比例3。

縱觀第三點,你可以看到那句「... 此實數通過取精確值...轉換爲十進制值」。您獲得的值(0.0000000000000000000000000001)是您開始使用的輸入文字(1.123456789123456789123456789E-28M)的轉換結果。當然,根據第三個要點的第二部分,如果有必要,轉換爲「...」的值按照銀行家的舍入舍入到最接近的可表示值...「。

對於decimal這是真實的,但對於floatdouble,指數符號可以由數據類型本身保留,所以不需要轉換/舍入。

增加:

要在上面進一步擴大,請參見:https://msdn.microsoft.com/en-us/library/364x0z75.aspx

這是decimal數據類型的定義。如上所述:decimal的範圍是(-7.9 x 1028 to 7.9 x 1028)/(100 to 28)28 to 29 significant digits。你的文字1.123456789123456789123456789E-28M超出了這個限制,所以當它被轉換時,1的右邊的所有內容都按上述規則舍入。

解決方案(?):

如果你需要比decimal較大的精度可以提供,你可能想尋找到實現自己的類,它是絕對可行的。考慮尋找想法的C#實現BigDecimal

一個實現我的一個快速谷歌發現:https://gist.github.com/nberardi/2667136

我不能給它的正確性說話,但它至少可以爲你的起點。

1

floatdouble是浮點數。這意味着他們分別持有數字和指數係數,其中doublefloat的雙倍大小。如果精度很重要,例如價格,建議不要使用double
decimal以「十進制」形式持有數字,並帶有固定點。這更精確,特別是使用小數計算。
看起來double更可能是你要找的東西。