W nagłówkach stdint.h
(C99), boost / cstdint.hpp i cstdint
(C ++ 0x) znajduje się między innymi typ int32_t
.
Czy istnieją podobne typy zmiennoprzecinkowe o stałym rozmiarze? Coś jak float32_t
?
W nagłówkach stdint.h
(C99), boost / cstdint.hpp i cstdint
(C ++ 0x) znajduje się między innymi typ int32_t
.
Czy istnieją podobne typy zmiennoprzecinkowe o stałym rozmiarze? Coś jak float32_t
?
sizeof
operatora. Taki typ byłby przydatny, gdy algorytm wymaga, aby był to znany określony rozmiar.
sizeof
rozwiązać problem konsekwentnego krosowania i niesprawdzania typów pływających?
Odpowiedzi:
Obecnie nic takiego nie istnieje w standardach C lub C ++. W rzeczywistości nie ma nawet gwarancji, że w float
ogóle będzie binarnym formatem zmiennoprzecinkowym.
Niektóre kompilatory gwarantują, że float
typem będzie 32-bitowy format binarny IEEE-754. Niektórzy nie. W rzeczywistości float
jest to w rzeczywistości single
typ IEEE-754 na większości platform niezintegrowanych, chociaż mają zastosowanie zwykłe zastrzeżenia dotyczące niektórych kompilatorów oceniających wyrażenia w szerszym formacie.
Istnieje grupa robocza omawiająca dodanie powiązań języka C w wersji 2008 IEEE-754, która mogłaby rozważyć zalecenie dodania takiego typu. Gdyby to zostało dodane do C, spodziewam się, że standard C ++ pójdzie w ich ślady ... w końcu.
Jeśli chcesz wiedzieć, czy float
jest to 32-bitowy typ IEEE, sprawdź std::numeric_limits<float>::is_iec559
. To stała czasu kompilacji, a nie funkcja.
Jeśli chcesz być bardziej kuloodporny, sprawdź również, czy std::numeric_limits<float>::digits
nie podstępnie używają standardu podwójnej precyzji IEEE dla float
. Powinno być 24.
Jeśli chodzi o long double
to, ważniejsze jest sprawdzenie, digits
ponieważ istnieje kilka formatów IEEE, którymi może być: 128 bitów (cyfry = 113) lub 80 bitów (cyfry = 64).
Nie byłoby to praktyczne float32_t
, ponieważ zwykle chcesz używać sprzętu zmiennoprzecinkowego, jeśli jest dostępny, i nie polegać na implementacji oprogramowania.
long double
Format na OS X (zarówno 32-bit i 64-bit Intel) jest dokładnie IEEE-754 podwójny format rozszerzony przechowywane w ostrokońcej kolejności. Nie ma w tym nic dziwnego. Bajty 0-7 zawierają pole istotności, a bajty 8 i 9 zawierają wykładnik i pola znaku.
5.0L
ma znaczenie a000000000000000
. Jego nieobciążony wykładnik wynosi +2, a podwójny rozszerzony wykładnik wynosi 3fff
, więc obciążony wykładnik dla 5,0L wynosi 4001
. Rzeczywisty wzorzec bajtów przechowywany w kolejności little-endian to 00 00 00 00 00 00 00 a0 01 40
, a jeśli zobaczysz to jako dwie 64-bitowe liczby całkowite little-endian, zobaczysz dokładnie to, co zaobserwowałeś.
4001
w little-endian jest 01 40 00 00 ...
Jeśli nic innego, najmniej znaczący bajt jest pierwszy. Spodziewam się, że sekwencja a0 01 40
pojawi się gdzieś w numerze (jeśli wykonali tylko rotację), ale nie sądzę, że wyjaśniłeś dlaczego a0
i 01 40
jesteś w całkowicie oddzielnych połówkach.
Jeśli uważasz, że posiadanie takich typów jak float32_t i float64_t jest niepraktyczne z jakichkolwiek powodów, musisz być zbyt przyzwyczajony do swojego znajomego systemu operacyjnego, kompilatora, że nie możesz zbytnio wyjrzeć poza swoje małe gniazdo.
Istnieje sprzęt, który natywnie obsługuje 32-bitowe operacje zmiennoprzecinkowe IEEE i inne, które wykonują 64-bitowe. Czasami takie systemy muszą nawet ze sobą rozmawiać, w takim przypadku niezwykle ważne jest, aby wiedzieć, czy double jest 32-bitowy, czy 64-bitowy na każdej platformie. Jeśli platforma 32-bitowa miałaby wykonywać nadmierne obliczenia w oparciu o wartości 64-bitowe z drugiej, możemy chcieć rzucić na niższą precyzję w zależności od wymagań dotyczących czasu i prędkości.
Osobiście czuję się nieswojo używając pływaków i podwójnych, chyba że wiem dokładnie, ile bitów znajduje się na mojej platformie. Tym bardziej, jeśli mam je przenieść na inną platformę przez jakiś kanał komunikacyjny.
Obecnie istnieje propozycja dodania następujących typów do języka:
decimal32
decimal64
decimal128
które pewnego dnia mogą być dostępne za pośrednictwem #include <decimal>
.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3871.html