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
?
c++
c
boost
floating-point
Pietro
źródło
źródło
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ścifloat
jest to w rzeczywistościsingle
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.
źródło
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 dlafloat
. 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.źródło
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 znaczeniea000000000000000
. Jego nieobciążony wykładnik wynosi +2, a podwójny rozszerzony wykładnik wynosi3fff
, więc obciążony wykładnik dla 5,0L wynosi4001
. Rzeczywisty wzorzec bajtów przechowywany w kolejności little-endian to00 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 jest01 40 00 00 ...
Jeśli nic innego, najmniej znaczący bajt jest pierwszy. Spodziewam się, że sekwencjaa0 01 40
pojawi się gdzieś w numerze (jeśli wykonali tylko rotację), ale nie sądzę, że wyjaśniłeś dlaczegoa0
i01 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.
źródło
Obecnie istnieje propozycja dodania następujących typów do języka:
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
źródło