#programowanie #cplusplus #programista15k Zacząłem się interesować słynnym problemem Fast Inverse Square Root z Quakea. I w sumie mógłby mi ktoś powiedzieć jaką wartość posiadam pod zmienną wynikTestu? Dlaczego rzutowanie na inta daje dziwną wartość, a na floata normalną?
int main() { float test = 69.420; int wynikTestu = *(int*)&test cout<<wynikTestu<<endl; }
@jaksa0: Binarnie. Tak samo masz pojedynczą i podwójną precyzję w liczbach zmiennoprzecinkowych. Wiadomo że nie da się dokładnie zapisać liczby zmiennoprzecinkowej. Masz mantysę gdzie się przechowuje liczbę po przecinku i cechę czyli wykładnik. Więc mam test zapisany we floacie a w wynik wpisuję zdereferowany adres pamięci czyli to co się pod nim znajduje. Mnie zastanawia dlaczego konwersja na (int*) czyli wskaźnik na inta daje taką dziwną wartość skoro wynikTestu jest intem,
@jaksa0: Chodzi o to że jak rzutuję wskaźnik na wskaźnik na inta to wtedy to co jest pod adresem czyli liczba float jest niezmienione (więc bity zostają łącznie ze znakiem) i otwieram to po prostu jako inta?
@przemyslaw-maczka: tak, rzutowanie wskaźników nie zmienia tego, co pod tym adresem się znajduje. Zmienia się jedynie sposób w jaki adresy są inkrementowane oraz to jak wyłuskuje dane spod tego adresu (w tym przypadku odczytuje je tak jakby tam był int)
@przemyslaw-maczka: no tak, czemu miały by się zmieniać bity? 4 bajty to 4 bajty. Ty tylko mówisz teraz traktuj te 4 bajty pamięci jak by to był int nie float.
@przemyslaw-maczka: Tutaj masz jak to binarnie wygląda. W gruncie rzeczy pod spodem jest taka sama wartość tylko inaczej interpretowana. (W xmm0 jest przechowywana wartość wynikTestu. Interesuje cię w tym momencie ta 1 wartość z v4_float)
@Dalegor_: Znaczy ja mniej więcej wiedziałem jak (T*)działa, tylko jakoś nigdy w mojej historii programowania nie miałem okazji konwertować tak z float& do int* i chyba mnie to zaskoczyło aż za bardzo. Poniekąd żałuję że tutaj napisałem bo zamiast wyjaśnić sprawę to dostałem odpowiedź żebym się o kodzie binarnym uczył :D Mimo wszystko dzięki za poświęcony trud.
Edit: może jednak nie wiedziałem skoro zaskoczeniem także było int wynikTestu = *(float*)&test
Edit: może jednak nie wiedziałem skoro zaskoczeniem także było int wynikTestu = *(float*)&test że działa poprawnie :D
@przemyslaw-maczka: Tutaj już zasługa kompilatora za implicit conversion. W tym przypadku kompilator stara się przekonwertować floata na inta w miarę bezstratnie i o dziwo bezpośrednio za pomocą instrukcji procesora (w moim przypadku CVTTSS2SI, sam sposób konwersji może się różnić). Masz tutaj picrel jak to działa w kodzie assembly.
@przemyslaw-maczka: i dobrze, że nie miałeś okazji. Fajnie jest raz czy dwa to zobaczyć i przekonać się jak są przechowywane dane w komputerze, ale w kodzie produkcyjnym rzutowanie wskaźników to źródło potencjalnych trudnych do znalezienia błędów. Szczególnie w c++, gdzie w ogóle powinno się w miarę możliwości unikać gołych wskaźników.
Faceci po 30tce którzy pracują zdalnie. Gdzie wy znajdujecie nowych znajomych, koleżanki czy kolegów? Jestem strasznie zdesperowany brakiem nowych relacji. Jestem sam jak palec. Relacje podupadły, ludziom nie chce wychodzić się z domu. Jak żyć? #zycie #zwiazki #relacje
#znajomi na początku roku zorientowałem się, że to ja piszę pierwszy do znajomych, więc postanowiłem nie pisać mamy sierpień nikt do mnie nie napisał z nich nawet jednej wiadomości, 15 lat znajomości xD ludzie to #!$%@? #przegryw
Zacząłem się interesować słynnym problemem Fast Inverse Square Root z Quakea. I w sumie mógłby mi ktoś powiedzieć jaką wartość posiadam pod zmienną wynikTestu? Dlaczego rzutowanie na inta daje dziwną wartość, a na floata normalną?
int main()
{
float test = 69.420;
int wynikTestu = *(int*)&test
cout<<wynikTestu<<endl;
}
@Arkadio88: Wyłożyłem się na tak prostej sprawie :D
(T*)
działa, tylko jakoś nigdy w mojej historii programowania nie miałem okazji konwertować tak z float& do int* i chyba mnie to zaskoczyło aż za bardzo. Poniekąd żałuję że tutaj napisałem bo zamiast wyjaśnić sprawę to dostałem odpowiedź żebym się o kodzie binarnym uczył :D Mimo wszystko dzięki za poświęcony trud.Edit: może jednak nie wiedziałem skoro zaskoczeniem także było
int wynikTestu = *(float*)&test
@przemyslaw-maczka: Tutaj już zasługa kompilatora za implicit conversion. W tym przypadku kompilator stara się przekonwertować floata na inta w miarę bezstratnie i o dziwo bezpośrednio za pomocą instrukcji procesora (w moim przypadku CVTTSS2SI, sam sposób konwersji może się różnić). Masz tutaj picrel jak to działa w kodzie assembly.