2017-02-20 53 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