Czy można konwertować int na float bez żadnych konsekwencji ?
Nie, z reguły sizeof(int) == sizeof(float)
, co oznacza, że float
ma mniejszą precyzję. Np. na moim systemie float ma 23 bity mantysy:
<@KrzaQ> { int a = (1 << 25) + 1; float b = a; cout << fixed << a, b; }
<+cxx> 33554433, 33554432.000000
Nie rozumiem, kiedy rzutuję na swoich komputerze z int na float to nic się nie zmienia.
Jeśli nie wychodzisz poza precyzję float
to się nie zmienia.
A kiedy mogę wyjść poza precyzję?
Kiedy masz więcej bitów znaczących niż ma mantysa twojego floata. Tak jak pokazałem to na przykładzie.
A czym są te bity znaczące?
To binarne cyfry znaczące liczby, którą chcesz reprezentować.
Czyli mantysa?
Chyba się nie rozumiemy. Mantysa musi mieć więcej lub tyle samo bitów co liczba, którą chcesz reprezentować, a więc liczba, którą chcesz reprezentować nie może mieć więcej bitów znaczących niż mantysa floata.
Mantysa float ma 23 bity a int do 31 chyba więc to dlatego nie można rzutować?
Tak jest. Chyba, że masz pewność, że wartości są bezstratnie reprezentowalne przez oba typy.
Tylko nie rozumiem dlaczego jak wpisuje dwa miliardy i rzutuje na float to nic nie zmienia.
2000000000
to binarnie 1110111001101011001010000000000
. Jak widać, cyfr znaczących jest 21.
A jak utworzyć taką liczbę?
Nie rozumiem. Jaką liczbę chcesz utworzyć i po co?
Taką w której będzie więcej niż 23 cyfry znaczące.
no po prostu sobie utwórz taką, w której są 24 lub więcej cyfry znaczące. Czyli po obcięciu zer zostają 24 cyfry. Np. 2 000 000 001 to 11101110011010110010100000000012
Nie można rzutować bez konsekwencji bo każda zmiennoprzecinkowa ma błąd niedomiaru albo nadmiaru przy operacjach, (zależy czy float czy double)
Nie przesadzajmy z każda. Tak długo jak nie wychodzisz poza precyzję (czyli np. w dziedzinę niereprezentowalnych liczb) błędu nie ma. Np.
double a = 2, b = 2, c = 2, d = 6;
assert(a * b + c == d);