2010-08-14 14 views

Odpowiedz

27

Wynik może nie pasować do int (lub długiego). Zakres podwójny jest znacznie większy.

Przybliżony zakres dwukrotnie: ± 5,0 x 10 -324 ± 1,7 x 10

(Source)

+0

Powiedzieli lub długo w pytaniu. – bwawok

+3

Punkt pozostaje ten sam."Podwójny" może być większy niż 9223372036854775807. – dan04

+1

Pomyślałem, że to byłby powód, ale po prostu chciał się upewnić. Oczywiście zaokrąglanie do liczby całkowitej * większe * niż długie jest rzadkością w przypadku * większości aplikacji *, Microsoft wciąż musiał ją wdrożyć w sensie matematycznym. Dzięki! – TheCloudlessSky

-2

Nie ma powodu, podane na docs, że udało mi się znaleźć. Domyślam się, że jeśli pracujesz z debelami, prawdopodobnie chcesz, aby każda operacja w grze podwójnej zwróciła podwójną. Zaokrąglenie go do rzutu na int zostało uznane przez projektanta języków za mniej powszechny niż zaokrąglanie i trzymanie jako podwójne.

Można napisać własną metodę, z których oddano go do int dla Ciebie w ciągu około 2 linii kodu, i znacznie mniej pracy niż zadaj pytanie na przepełnienie stosu ...

+2

Oczywiście pisanie własnych jest banalne, ale odpowiedź Marka zapewnia wgląd. StackOverflow nie zawsze chodzi o "jak", ja też lubię to "dlaczego" :) – si618

+3

-1 - Wiem * jak *, zastanawiam się * dlaczego *. Twoja odpowiedź nie ma nawet sensu. – TheCloudlessSky

8

zgadzam się z odpowiedzią, że Marka Wynik może nie pasować do long, ale możesz się zastanawiać: co jeśli C# miał znacznie dłuższy typ long? Cóż, oto co się dzieje w Pythonie z jego całkowitymi arbitralne długości:

>>> round(1.23e45) 
1229999999999999973814869011019624571608236032 

Większość cyfr są „szum” z zmiennoprzecinkowych zaokrąglenia błąd. Być może część motywacji do odzyskania Round/ w C# było uniknięcie złudzeń fałszywej precyzji.

Alternatywnym wyjaśnieniem jest to, że moduł .NET Math używa kodu napisanego w języku C, w którym floor i ceil zwraca typy zmiennoprzecinkowe.

2

Poza argumentami, żadna z tych odpowiedzi nie rozwiązuje problemu, który jest dla mnie podstawowym problemem polegającym na zwracaniu liczby zmiennoprzecinkowej, gdy naprawdę chce się uzyskać dokładną liczbę całkowitą. Wydaje mi się, że obliczona liczba zmiennoprzecinkowa może być mniejsza lub większa od żądanej liczby całkowitej o mały błąd zaokrągleń, więc operacja rzutowania może spowodować wyłączenie o jeden błąd. Sądzę, że zamiast rzucać, musisz zastosować funkcję całkowitą (nie podwójną), najbliższą najbliższą, do podwójnego wyniku floor(). Albo napisz swój własny kod. Wersje biblioteki C floor() i ceil() są bardzo powolne.

Czy to prawda, czy też czegoś brakuje? Jest coś o dokładnej reprezentacji liczb całkowitych w standardzie zmiennoprzecinkowym IEEE, ale nie jestem pewien, czy to sprawia, że ​​obsada jest bezpieczna.

Wolałbym sprawdzać zakres w funkcji (jeśli jest to konieczne, aby uniknąć przepełnienia) i zwrócić długi. Dla własnego prywatnego kodu mogę pominąć sprawdzanie zakresu. Robiłem to:

long int_floor(double x) 
{ 
    double remainder; 
    long truncate; 
    truncate = (long) x;  // rounds down if + x, up if negative x 
    remainder = x - truncate; // normally + for + x, - for - x 
    //....Adjust down (toward -infinity) for negative x, negative remainder 
    if (remainder < 0 && x < 0) 
     return truncate - 1; 
    else 
     return truncate; 
} 

kreacji istnieją ceil() i round() z różnych względów dla liczb ujemnych i dodatnich.

+0

Jeśli chcesz, możesz odwzorować wartości zmiennoprzecinkowe na rzeczy, które można podać dla kodu wymagającego 'Int32' lub' Int64', mając metody do wykonywania takiego mapowania bezpośrednio za pomocą round-to-next-even lub round-towards - nieskończenie-nieskończoność byłaby pomocna. – supercat

+0

Operacja round-to-integer na float nie może utworzyć błędu zaokrąglania, który nie istnieje obecnie, ponieważ liczba całkowita powyżej największej liczby z częścią ułamkową jest dokładnie reprezentowana. – supercat

Powiązane problemy