Co czasu używam Math.Round/Floor/Ceiling
Zawsze rzucam do int
(lub, jeśli to konieczne, long
). Dlaczego dokładnie zwracają double
, jeśli zawsze zwraca liczbę całkowitą.Dlaczego Math.Round/Floor/Ceiling nie zwraca długiej lub int?
Odpowiedz
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
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 ...
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
-1 - Wiem * jak *, zastanawiam się * dlaczego *. Twoja odpowiedź nie ma nawet sensu. – TheCloudlessSky
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.
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.
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
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
- 1. Dlaczego ten bitowy LUB zwraca wartość null na int nullable?
- 2. dlaczego math.Ceiling (double a) nie zwraca int bezpośrednio?
- 3. javax.servlet.HttpServletRequest.getContentLength() zwraca tylko int.
- 4. Dlaczego przesyłanie/konwersja z int zwraca gwiazdkę
- 5. Dlaczego metoda InputStream # read() zwraca wartość int, a nie bajt?
- 6. Dlaczego java.util.zip.CRC32.getValue() zwraca długi, a nie int?
- 7. Dlaczego int * [] zanika w int **, ale nie int [] []?
- 8. Dlaczego Decimal.Divide (int, int) działa, ale nie (int/int)?
- 9. Dlaczego nie mogę przypisać "długiej" wartości 4 miliardów?
- 10. Dlaczego grupa nie sumuje konwersji boolean na int lub float?
- 11. Scala: dlaczego nie działa lista [=> Int]?
- 12. Dlaczego Int nie dziedziczy/nie rozszerza się z zamówionego [Int]
- 13. dlaczego null.asInstanceOf [Int] nie rzuca wyjątku NullPointerException?
- 14. Konwertuj z długiej na dwie wartości int i na odwrót
- 15. dlaczego getLastRequest nie zwraca niczego?
- 16. Dlaczego SignalProducer nie zwraca sygnału?
- 17. Dlaczego Scala ani Either.RightProjection # nie zwraca zwrotu?
- 18. Co zwraca operator ++ (lub -)?
- 19. Python hash() nie obsługuje długiej liczby całkowitej?
- 20. Dlaczego 0XAA jest niepodpisaną int, a nie int?
- 21. Dlaczego Python rozmowę __str__ zamiast zwracania wartości długiej
- 22. Dlaczego floor nie zwraca liczby całkowitej?
- 23. Dlaczego Array.Length int, a nie uint
- 24. Dlaczego funkcja! Int() nie działa poprawnie?
- 25. Dlaczego DateTime.Now.Year int i nie ushort
- 26. Sprawdź int lub listę <int>
- 27. Dlaczego nie piszemy int x = printf ("tekst"); ponieważ instrukcja printf() zwraca za każdym razem wartość całkowitą?
- 28. Dlaczego `Przyszłe # toString` zwraca` "List()" `?
- 29. Dlaczego CMSampleBufferGetImageBuffer zwraca NULL
- 30. Dlaczego TCusomWinSocket.ReceiveBuf nigdy nie zwraca 0?
Powiedzieli lub długo w pytaniu. – bwawok
Punkt pozostaje ten sam."Podwójny" może być większy niż 9223372036854775807. – dan04
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