2017-02-20 10 views
11

UżywamJak Decimal.Round() rzucać OverflowException

Decimal.Round(decimal d) 

MSDN twierdzi, że może rzucić OverflowException https://msdn.microsoft.com/en-us/library/k4e2bye2(v=vs.110).aspx

Nie jestem pewien, jak to może się zdarzyć. Próbowałem patrząc na realizację z użyciem ilSpy I dostał aż realizacja zewnętrzna:

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

Czy ktoś ma pojęcia, co wejście może rzucić ten wyjątek?

+5

http://stackoverflow.com/questions/3203959/overflow- wyjątek-kiedy-dzielenie-dwa-dziesiętne-w-sieci – Equalsk

+4

FWIW, [to gdzie] (https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/classlibnative/bcltype/decimal.cpp#L175) to wywołanie docelowe jest zaimplementowane w .NET Core CLR - możesz zobaczyć rzut "OverflowException" w linii 188. –

+3

I [ten pojawia się] (https://github.com/dotnet/coreclr/blob/32f0f9721afb584b4a14d69135bea7ddc129f755/src/ palrt/decarith.cpp # L1215) jako implementacja 'VarDecRound'. Na pierwszy rzut oka nie rozumiem, dlaczego zwróciłby wynik niepowodzenia do 'FCallRound' (powodując zgłoszenie wyjątku). Zwraca 'E_INVALIDARG', ale warunek tego został już sprawdzony przez' FCallRound' lub 'NOERROR', więc stwierdza, że' OverflowException' nie powinien być nigdy rzucany. –

Odpowiedz

3

Kiedy wychodzimy dalej od tego, co już odkryliście, kończymy na implementacji funkcji VarDecRound. Ta funkcja ma dokładnie jedną gałąź, w której zwraca kod błędu, i wtedy jego drugi argument jest mniejszy od zera. Ten argument oznacza liczbę cyfr po przecinku do rundy do:

if (cDecimals < 0) 
    return E_INVALIDARG; 

(tego rodzaju twierdzenie stanowi równowartość co za ArgumentException byłoby w .NET)

James Thorpe zauważył w komentarzu OP, podobna twierdzenie odbywa się dalej w górę łańcucha połączeń, here:

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

Wniosek:
Wykonanie może nie dotrzeć the point że skutkowałoby TH wioślarstwo OverflowException udokumentowane:

  1. OverflowException wydaje się być stosowany wewnętrznie jako catch-all mechanizm, podobnie jak OutOfMemoryException w GDI +
  2. dokumentacja nie odpowiada faktycznej realizacji
  3. OverflowException nawet nie zrobić sens koncepcyjnie. Zaokrąglania wartości w górę lub w dół w tego samego typu nie może przekroczyć integral min or max range, ponieważ wartość kandydat powinien sam być w zakresie (rounding method used)
Powiązane problemy