2017-02-20 54 views
11

我使用如何Decimal.Round()拋出OverflowException異常

Decimal.Round(decimal d) 

MSDN說,它可以拋出OverflowException https://msdn.microsoft.com/en-us/library/k4e2bye2(v=vs.110).aspx

我不知道怎麼說都有可能發生。我試圖尋找過使用ilSpy 實施和GOT直到外部實現的:

// decimal 
[SecurityCritical] 
[MethodImpl(MethodImplOptions.InternalCall)] 
private static extern void FCallRound(ref decimal d, int decimals); 

有誰有什麼線索輸入拋出此異常?

+5

http://stackoverflow.com/questions/3203959/overflow-例外時除以兩位十進制網內 – Equalsk

+4

FWIW,[這是其中](https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/classlibnative/bcltype/decimal.cpp#L175)該目標調用是在.NET Core CLR中實現的 - 您可以在第188行看到「OverflowException」的拋出。 –

+3

並且[出現](https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/ palrt/decarith.cpp#L1215)是'VarDecRound'的實現。乍一看,我看不出爲什麼它會將失敗結果返回給'FCallRound'(導致引發異常)。它或者返回'E_INVALIDARG',但是它的條件已經被'FCallRound'或'NOERROR'檢查過了,所以它看起來'OverflowException'實際上不應該被拋出。 –

回答

3

當我們離你已經發現的更遠的時候,我們最終實現了VarDecRound函數。該函數只有一個分支,它返回一個錯誤代碼,並且它的第二個參數cDecimals小於零。這個參數指示的小數位數進行四捨五入爲:

if (cDecimals < 0) 
    return E_INVALIDARG; 

(這種說法的是一個什麼樣的ArgumentException將.NET中的等價物)

正如詹姆斯·索普在評論中指出的OP,類似的斷言被進一步完成了調用鏈,here

if (decimals < 0 || decimals > 28) 
    FCThrowArgumentOutOfRangeVoid(...) 

結論:
執行不能達到the point將導致日賽艇OverflowException的記載:

  1. 發生OverflowException似乎已經在內部使用作爲一個包羅萬象的機制,就像OutOfMemoryException異常在GDI +
  2. 文檔不符合實際的實施
  3. 發生OverflowException甚至沒有在概念上感覺。舍入在相同的數據類型的值向上或向下不可能超過一個integral min or max range,因爲候選值本身必須是在範圍(rounding method used