Czy jest jakaś różnica między tymi:
float foo1 = (int)(bar / 3.0);
float foo2 = floor(bar / 3.0);
Jak rozumiem, oba przypadki mają ten sam wynik. Czy jest jakaś różnica w skompilowanym kodzie?
c++
c
floating-point
OgreSwamp
źródło
źródło
floor
, ale uważaj, todouble
nie jest dlafloat
. C99 ma równieżfloorf
dlafloat
.#include<cmath>
i używajstd::floor
)bar
?Odpowiedzi:
Rzutowanie na int zostanie obcięte do zera.
floor()
skróci się w kierunku ujemnej nieskończoności. To da ci różne wartości, jeślibar
były ujemne.źródło
floor()
jest intencja, jest to, czy wartośćbar
jest zbyt duża, aby zmieścić się wint
.Jak powiedziano wcześniej, dla liczb dodatnich są one takie same, ale różnią się dla liczb ujemnych. Zasada jest taka, że int zaokrągla się w kierunku 0, podczas gdy floor zaokrągla w kierunku ujemnej nieskończoności.
To powiedziawszy, istnieje również różnica w czasie wykonania. W moim systemie mierzyłem czas, że rzucanie jest co najmniej 3 razy szybsze niż podłoga.
Mam kod, który wymaga działania z ograniczonym zakresem wartości, w tym liczb ujemnych. I musi być bardzo wydajne, więc używamy do tego następującej funkcji:
Oczywiście to się nie powiedzie dla bardzo dużych wartości x (napotkasz problemy z przepełnieniem) i dla wartości ujemnych poniżej -100000 itd. Ale taktowałem tak, aby był co najmniej 3 razy szybszy niż floor, co było naprawdę krytyczne dla naszej aplikacji. Weź to z przymrużeniem oka, przetestuj na swoim systemie itp., Ale warto rozważyć IMHO.
źródło
float
, niedouble
- być możedouble
była to Twoja aplikacja. Jeśli w C, pamiętaj, aby użyćfloorf()
zfloat
s.SO 101, nie zmieniaj swojego pytania po tym, jak ludzie odpowiedzieli na Twoje pytanie, zamiast tego napisz nowe pytanie.
Jak myślisz, dlaczego będą miały ten sam wynik?
źródło
fabs
? Pytanie dotyczyłofloor
. Podłoga0.33333
... jest0
.EDYCJA: Ponieważ pytanie mogło zostać zmodyfikowane z powodu pomyłki między
fabs()
afloor()
.Biorąc pod uwagę oryginalne przykładowe wiersze pytania:
Różnica polega na tym, że jeśli słupek jest ujemny, wynik będzie ujemny z pierwszym, ale dodatni z drugim. Pierwsza zostanie obcięta do liczby całkowitej, a druga zwróci pełną wartość dziesiętną, w tym część ułamkową.
źródło
Tak.
fabs
zwraca wartość bezwzględną swojego argumentu, a rzutowanie na wartość int powoduje obcięcie dzielenia (w dół do najbliższej liczby całkowitej), więc wyniki będą prawie zawsze inne.źródło
Istnieją dwie główne różnice:
Jak inni zauważyli, rzutowanie na liczbę całkowitą będzie skracane do zera, podczas gdy
floor()
zawsze będzie obcięte w kierunku ujemnej nieskończoności; jest to inne zachowanie dla argumentu ujemnego.Wydaje się, że nikt (jeszcze) nie zwrócił uwagi na inną różnicę - jeśli argument jest większy lub równy
MAX_INT+1
(lub mniejszy niż-MAX_INT-1
), rzutowanie na aint
spowoduje odrzucenie najwyższych bitów (prawdopodobnie C) lub niezdefiniowane zachowanie ( C ++ i prawdopodobnie C). Na przykład, jeśli maszint
32 bity, będziesz mieć tylko bit znaku plus 31 bitów danych. Więc użycie tego zdouble
dużym rozmiarem da niezamierzone rezultaty.źródło
int
przepełnienie jest to, że argument jest większy lub równyINT_MAX
+1. Symetrycznie warunkiem niedomiaru jest to, że argument jest mniejszy lub równyINT_MIN
-1.(int) x
jest żądaniem zachowania części całkowitejx
(nie ma tu zaokrąglania)fabs(x)
= | x | tak, że jest>= 0
;Np .:
(int) -3.5
zwraca-3
;fabs(-3.5)
zwroty3.5
;Ogólnie
fabs (x) >= x
dla wszystkich x;x >= (int) x
Jeślix >= 0
x < (int) x
Jeślix < 0
źródło