Czy jest jakaś różnica między nimi:Obsada int vs piętrze
float foo1 = (int)(bar/3.0);
float foo2 = floor(bar/3.0);
Jak rozumiem oba przypadki mają ten sam rezultat. Czy jest jakaś różnica w skompilowanym kodzie?
Czy jest jakaś różnica między nimi:Obsada int vs piętrze
float foo1 = (int)(bar/3.0);
float foo2 = floor(bar/3.0);
Jak rozumiem oba przypadki mają ten sam rezultat. Czy jest jakaś różnica w skompilowanym kodzie?
odlewnicze do int będzie obciąć do zera. floor()
spowoduje obcięcie w kierunku ujemnego nieskończoności. Da ci to różne wartości, jeśli bar
będzie ujemny.
Myślę, że trafiłeś w sedno tutaj. Inną różnicą, jeśli 'floor()' jest intencją, jest jeśli wartość 'bar' jest zbyt duża, aby zmieścić się w' int'. –
Czy masz jakieś źródło tego stwierdzenia? – HelloGoodbye
EDYCJA: Ponieważ pytanie mogło zostać zmodyfikowane z powodu pomyłki między fabs()
i floor()
.
Podane oryginalne przykładowe pytanie linie:
1. float foo = (int)(bar/3.0);
2. float foo = fabs(bar/3.0);
Różnica polega na tym, że jeśli pasek jest ujemny wynik będzie ujemny z pierwszym ale pozytywny z drugim. Pierwsza zostanie obcięta do liczby całkowitej, a druga zwróci pełną wartość dziesiętną, w tym część ułamkową.
Jak myślisz, dlaczego będą one miały taki sam rezultat?
float foo = (int)(bar/3.0) //will create an integer then assign it to a float
float foo = fabs(bar/3.0) //will do the absolute value of a float division
bar = 1.0
foo1 = 0;
foo2 = 0.33333...
Tak. fabs
zwraca bezwzględną wartość swojego argumentu, a rzutowanie na int powoduje obcięcie podziału (w dół do najbliższej int), więc wyniki prawie zawsze będą różne.
(int) x
jest prośba, aby utrzymać część całkowitą x
(nie ma tu zaokrągleń)
fabs(x)
= | x | tak, że jest to >= 0
;
Np .: (int) -3.5
zwraca -3
; fabs(-3.5)
zwraca 3.5
;
Ogólnie rzecz biorąc, fabs (x) >= x
dla wszystkich x;
x >= (int) x
jeśli x >= 0
x < (int) x
jeśli x < 0
Twoje ostatnie zdanie jest błędne; rozważ swój przykład -3. –
x = -3 fabs (-3) = 3 (int) -3 = -3; Myślę, że ostatnie nierówności utrzymują się. Czy możesz dokładniej wyjaśnić, dlaczego jest nie tak? –
Przepraszam, miałem na myśli -3,5, przykład, który podałeś. -3> -3.5 –
Jak już wcześniej wspomniano, dla liczb dodatnich są one takie same, ale różnią się liczbami ujemnymi. Zasadą jest, że int zaokrągla się w kierunku 0, podczas gdy podłoga zaokrągla się w kierunku ujemnej nieskończoności.
floor(4.5) = (int)4.5 = 4
floor(-4.5) = -5
(int)(-4.5) = -4
Jest to również różnica w czasie realizacji. W moim systemie czas był taki, że rzut jest co najmniej 3 razy szybszy niż podłoga.
Mam kod, który wymaga operacji piętra o ograniczonym zakresie wartości, w tym liczb ujemnych. I to musi być bardzo wydajny, więc używamy następującą funkcję do niego:
int int_floor(double x)
{
return (int)(x+100000) - 100000;
}
Oczywiście będzie to fail dla bardzo dużych wartości x (wpadniemy w niektórych kwestiach przelewowe) oraz dla wartości ujemnych poniżej - 100000 itd. Ale zmusiłem go do tego, aby był co najmniej 3 razy szybszy od podłogi, co było bardzo ważne dla naszej aplikacji. Weź to z przymrużeniem oka, przetestuj na swoim systemie itp.ale warto wziąć pod uwagę IMHO.
Istnieją dwa główne różnice:
jak inni wykazali, odlewanie do całkowitej będzie obciąć do zera, podczas gdy floor()
zawsze obciąć do minus nieskończoności; to jest inne zachowanie dla negatywnego argumentu.
nikt (jeszcze) wydaje się, że wskazał inną różnicę - jeśli argument jest większy lub równy MAX_INT+1
(lub mniej niż -MAX_INT-1
), a następnie rzucając na int
spowoduje górnym większości bitów przed upadkiem (Prawdopodobnie C) lub niezdefiniowane zachowanie (C++ i ewentualnie C). EG jeśli twój int
ma 32 bity, będziesz miał tylko bit znaku i 31 bitów danych. Używanie tego z dużym rozmiarem spowoduje uzyskanie niezamierzonych rezultatów.
2.a. Dokładny warunek konwersji na przepełnienie 'int' jest taki, że argument jest większy lub równy' INT_MAX' + 1. Symetrycznie warunkiem niedomiaru jest to, że argument jest mniejszy lub równy "INT_MIN"-1. –
2.b. Przepełnienie w konwersji z liczby zmiennoprzecinkowej na całkowitą jest niezdefiniowanym zachowaniem w C++. Nie "powoduje to upuszczenia najwyżej położonych bitów". Zobacz (chociaż jest napisane dla C): http://blog.frama-c.com/index.php?post/2013/10/09/Overflow-float-integer –
@PascalCuoq naprawiony – abligh
nieco lepiej z 'podłogą', ale uważaj, że jest to dla' double' nie dla 'float'. C99 ma również 'floorf' dla' float'. –
Więc mają ten sam wynik, o ile pasek jest dodatni – Zac