2017-02-20 17 views
11

Tôi đang sử dụngLàm thế nào có thể Decimal.Round() ném OverflowException

Decimal.Round(decimal d) 

MSDN nói nó có thể ném OverflowException https://msdn.microsoft.com/en-us/library/k4e2bye2(v=vs.110).aspx

Tôi không chắc chắn làm thế nào mà có thể xảy ra. Tôi đã cố gắng nhìn qua việc thực hiện sử dụng ilSpy Và có cho đến khi thực hiện bên ngoài của:

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

Có ai có một đầu mối những gì đầu vào có thể ném ngoại lệ này?

+5

http://stackoverflow.com/questions/3203959/overflow- exception-when-dividing-two-decimals-in-net – Equalsk

+4

FWIW, [đây là nơi] (https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/classlibnative/bcltype/decimal.cpp#L175) rằng cuộc gọi đích được thực hiện trong .NET Core CLR - bạn có thể thấy cú ném 'OverflowException' trên dòng 188. –

+3

Và [điều này xuất hiện] (https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/ palrt/decarith.cpp # L1215) để thực hiện 'VarDecRound'. Thoạt nhìn, tôi không thể thấy tại sao nó sẽ trả về kết quả thất bại cho 'FCallRound' (kết quả là ngoại lệ bị ném). Nó trả về 'E_INVALIDARG', nhưng điều kiện cho điều đó đã được kiểm tra bởi' FCallRound', hoặc 'NOERROR', vì vậy nó _seems_ rằng' OverflowException' không thực sự được ném ra. –

Trả lời

3

Khi chúng tôi đi xa hơn những gì bạn đã tự khám phá, chúng tôi sẽ thực hiện chức năng VarDecRound. Hàm này có chính xác một nhánh mà nó trả về một mã lỗi, và đó là khi đối số thứ hai của nó cDecimals nhỏ hơn 0. Lập luận này cho biết số chữ số thập phân để vòng để:

if (cDecimals < 0) 
    return E_INVALIDARG; 

(loại này khẳng định là tương đương với những gì một ArgumentException sẽ là trong .NET)

Như James Thorpe chỉ ra trong một chú thích trên OP, một sự khẳng định tương tự được thực hiện thêm lên chuỗi cuộc gọi, here:

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

Kết luận:
thực hiện có thể không đạt được the point rằng sẽ cho kết quả trong ngày chèo OverflowException như tài liệu:

  1. OverflowException dường như đã được sử dụng trong nội như một nhận tất cả cơ chế, giống như OutOfMemoryException trong GDI +
  2. Các tài liệu không phù hợp với thực tế triển khai
  3. OverflowException thậm chí không thực hiện ý nghĩa khái niệm. Làm tròn một giá trị lên hoặc xuống trong các loại dữ liệu giống nhau không thể nào vượt quá một integral min or max range, vì giá trị ứng cử viên thân phải nằm trong phạm vi (rounding method used)
Các vấn đề liên quan