Jak zaokrąglić liczbę dziesiętną (zmiennoprzecinkową) do najbliższej liczby całkowitej?
na przykład
1.2 = 1
1.7 = 2
źródło
Jak zaokrąglić liczbę dziesiętną (zmiennoprzecinkową) do najbliższej liczby całkowitej?
na przykład
1.2 = 1
1.7 = 2
Wyjście perldoc -q round
Czy Perl ma funkcję round ()? A co z ceil () i floor ()? Funkcje wyzwalania?Pamiętaj, że
int()
po prostu skraca się w kierunku0
. Zaokrągla do określonej liczby cyfrsprintf()
lubprintf()
jest zwykle najłatwiejszą trasą.
printf("%.3f", 3.1415926535); # prints 3.142
POSIX
Moduł (część standardowego rozkładu Perl) narzędziaceil()
,floor()
oraz szereg innych funkcji matematycznych i trygonometrycznych.
use POSIX; $ceil = ceil(3.5); # 4 $floor = floor(3.5); # 3
Od 5000 do 5,003 perlów trygonometria została wykonana w
Math::Complex
module. W 5.004Math::Trig
moduł (część standardowej dystrybucji Perla) implementuje funkcje trygonometryczne. Wewnętrznie wykorzystujeMath::Complex
moduł, a niektóre funkcje mogą wyłamać się z rzeczywistej osi na płaszczyznę zespoloną, na przykład odwrotny sinus 2.Zaokrąglanie wniosków finansowych może mieć poważne konsekwencje, dlatego należy dokładnie określić zastosowaną metodę zaokrąglania. W takich przypadkach prawdopodobnie opłaca się nie ufać jakimkolwiek zaokrągleniom systemowym używanym przez Perl, ale zamiast tego zaimplementować funkcję zaokrąglania, której potrzebujesz.
Aby zobaczyć, dlaczego, zwróć uwagę, że nadal będziesz mieć problem z przemianą w połowie punktu:
for ($i = 0; $i < 1.01; $i += 0.05) { printf "%.1f ",$i} 0.0 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.4 0.4 0.5 0.5 0.6 0.7 0.7 0.8 0.8 0.9 0.9 1.0 1.0
Nie wiń Perla. Jest tak samo jak w C. IEEE mówi, że musimy to zrobić. Liczby Perla, których wartości bezwzględne są liczbami całkowitymi poniżej
2**31
(na komputerach 32-bitowych), będą działać podobnie jak matematyczne liczby całkowite. Inne numery nie są gwarantowane.
printf
jeśli chcesz, aby wynik był w zmiennej, użyjsprintf
...int()
na PDL?Nie zgadzając się ze złożonymi odpowiedziami dotyczącymi znaków w połowie i tak dalej, dla bardziej powszechnego (i być może trywialnego) przypadku użycia:
my $rounded = int($float + 0.5);
AKTUALIZACJA
Jeśli możliwe, że twój wynik
$float
będzie ujemny, następująca zmiana da prawidłowy wynik:my $rounded = int($float + $float/abs($float*2 || 1));
Przy takim obliczeniu -1,4 jest zaokrąglane do -1, a od -1,6 do -2, a zero nie eksploduje.
źródło
Możesz użyć modułu takiego jak Math :: Round :
Lub możesz to zrobić w brutalny sposób:
źródło
Jeśli zdecydujesz się użyć printf lub sprintf, pamiętaj, że używają one metody Round half to even .
źródło
Zobacz perldoc / perlfaq :
źródło
Nie potrzebujesz żadnego zewnętrznego modułu.
Być może nie rozumiem, ale pomyślałem, że to znacznie czystszy sposób na wykonanie tej samej pracy.
To co robi to przejście przez każdą liczbę dodatnią w elemencie, wypisanie liczby i zaokrąglonej liczby całkowitej we wspomnianym formacie. Kod łączy odpowiednie zaokrąglone dodatnie liczby całkowite tylko na podstawie liczb dziesiętnych. int ($ _) zasadniczo zaokrągla liczbę w dół, więc ($ -int ($ )) przechwytuje ułamki dziesiętne. Jeśli liczby dziesiętne są (z definicji) dokładnie mniejsze niż 0,5, zaokrąglij liczbę w dół. Jeśli nie, zaokrąglij w górę, dodając 1.
źródło
Poniższe działania zaokrągla liczby dodatnie lub ujemne do podanej pozycji dziesiętnej:
źródło
Poniżej znajduje się próbka pięciu różnych sposobów sumowania wartości. Pierwsza to naiwny sposób wykonania sumowania (i zawodzi). Druga próba użycia
sprintf()
, ale też się nie udaje. Trzeci używasprintf()
pomyślnie, podczas gdy ostatnie dwa (czwarte i piąte) używająfloor($value + 0.5)
.Zwróć uwagę, że
floor($value + 0.5)
można go zastąpić,int($value + 0.5)
aby usunąć zależność odPOSIX
.źródło
Liczby ujemne mogą dodawać pewne dziwactwa, o których ludzie muszą wiedzieć.
printf
Podejścia w stylu dają nam prawidłowe liczby, ale mogą powodować dziwne wyświetlanie. Odkryliśmy, że ta metoda (moim zdaniem głupio) stawia-
znak, czy powinna, czy nie. Na przykład, -0,01 zaokrąglone do jednego miejsca po przecinku zwraca -0,0, a nie tylko 0. Jeśli masz zamiar zastosowaćprintf
podejście stylowe i wiesz, że nie chcesz, użyj%d
i nie%f
(jeśli potrzebujesz miejsc po przecinku, wtedy wyświetlacz staje się niewyraźny).Chociaż jest poprawny i dla matematyki nic wielkiego, w przypadku wyświetlania wygląda po prostu dziwnie, pokazując coś w rodzaju „-0,0”.
W przypadku metody int liczby ujemne mogą w rezultacie zmienić to, co chcesz (chociaż istnieje kilka argumentów, które można uczynić, że są poprawne).
int + 0.5
Powoduje rzeczywiste problemy z numerami -wykluczające, chyba że chcesz to działa w ten sposób, ale wyobrażam sobie, że większość ludzi nie. -0,9 powinno prawdopodobnie zaokrąglić do -1, a nie 0. Jeśli wiesz, że chcesz, aby wartość ujemna była sufitem, a nie podłogą, możesz to zrobić w jednej linii, w przeciwnym razie możesz chcieć użyć metody int z drugorzędnym modyfikacja (to oczywiście działa tylko w celu odzyskania liczb całkowitych:źródło
Moje rozwiązanie dla sprintf
źródło
Jeśli zależy ci tylko na uzyskaniu wartości całkowitej z całej liczby zmiennoprzecinkowej (tj. 12347,9999 lub 54321,0001), to podejście (pożyczone i zmodyfikowane z góry) załatwi sprawę:
źródło
mnóstwo dokumentacji na temat zaokrąglania liczb, wielu ekspertów sugeruje pisanie własnych procedur zaokrąglania, ponieważ wersja „gotowa” dostarczona z Twoim językiem może nie być wystarczająco dokładna lub zawierać błędy. wyobrażam sobie jednak, że mówią o wielu miejscach po przecinku, a nie tylko o jednym, dwóch lub trzech. mając to na uwadze, oto moje rozwiązanie (chociaż nie DOKŁADNIE zgodnie z wymaganiami, ponieważ moje potrzeby to wyświetlanie dolarów - proces nie różni się jednak zbytnio).
źródło
if ($digit3 >= 5) { $digit3 = 0; $digit2++; if ($digit2 > 9) { $digit2 = 0; $digit1++; if ($digit1 > 9) { $digit1 = 0; $cost[0]++; } } }
więc jest:if ($digit1 >= 5) { $digit1 = 0; $cost[0]++; }
wtedy po prostureturn commafied($cost[0]);
źródło