C++ declare platform independent 32-bit float
Solution 1
You're using Qt. which is specific to C++, so I'm not sure why the question is tagged C.
As far as I know, on all platforms where Qt is supported, type float
is 32-bit IEEE.
If somebody decides to port Qt to, say, a Cray vector machine with 64-bit float
, you're not going to have a 32-bit floating-point type anyway (unless you implement it yourself in software, but I don't see how that would be useful).
There is no <stdfloat.h>
/ <cstdfloat>
corresponding to <stdint.h>
/ <cstdint>
. C and C++ provide float
, double
, and long double
, and imposes minimal requirements on them, but doesn't give you a way to ask for a floating-point type of any specific size.
Your best bet is probably to add something like this in main
, or in some function that's guaranteed to be called during program startup:
assert(CHAR_BIT * sizeof (float) == 32);
and perhaps CHAR_BIT == 8
as well if your code implicitly depends on that.
It's unlikely that the assert
will ever fire -- and if it does, you've got bigger problems.
You might want to reconsider whether you really need a 32-bit floating type. If your code were running on a system with 64-bit float
, how would that fail to meet your requirements?
Solution 2
There isn't such a sized floating point type, but you can always statically assert that the size is 32 bits. Maybe even something as simple as a global char array:
#include <climits>
char static_assert_float32[1 - (2 * ((sizeof(float) * CHAR_BIT) != 32))];
This will fail to compile if float
is not 32 bits by declaring an array of negative size.
Solution 3
Most common implementations of C and C++ will use 32 bit float
types. If you really need to catch any platforms where that won't be the case you can use the following to throw an error early in the program:
#include <limits.h>
if (sizeof(float) * CHAR_BIT != 32)
// error code here
Unfortunately I don't know of a way to detect it at compile time, my earlier answer was flawed.
Solution 4
On a platfrom that supports IEEE-754 float
it's going to be 32 bit. On platforms that don't, different width will probably be the least of your problems. Bottom line - use float
and don't worry.
Solution 5
The Boolean static member constant std::numeric_limits<float>::is_iec559
is true if and only if float
conforms to the IEC 559/IEEE 754 floating-point standard. You'll need to #include
the header <limits>
.
Note that this alone doesn't tell you whether or not float
is specifically 32-bit IEEE floating point, just that it is IEEE floating point -- some implementation without 32-bit floating point hardware might, for example, choose float
be 64-bit IEEE floating point.
Related videos on Youtube
Ilya Kobelevskiy
Updated on June 01, 2020Comments
-
Ilya Kobelevskiy almost 4 years
Is there a way to declare 32-bit floating point value in C++ - ensuring that it will always be 32 bits regardless of platform/compiler?
I can do that for integers like that:
#include <stdint.h> uint32_t var; //32 bit unsigned integer uint64_t var1; //64 bit unsigned integer
is there a way to do something like that for floats? As far as I know,
float var; //Usually is 32 bit, but NOT GUARANTEED to be 32 bit
is implementation specific, and is not necessarily 32 bit.. (Correct me if I am wrong).
I am using qt, so if there is any solution using it I would accept it - I couldn't find anything like quint16 for floats (qreal changes size depending on platform).
-
Admin over 10 yearsNo - some platforms may have decimal floats.
-
David Heffernan over 10 yearsWhat are you going to do with a 32 bit binary floating point data type on a platform without support for that?
-
Mats Petersson over 10 yearsSo exactly what do you want to have happen if
float
isn't 32-bits? One can of course make a checkif (sizeof(float) != 4 && CHAR_BITS == 8) PANIC("Not 32-bit float!!!");
- but I'm not sure what you expect the compiler to do instead, if there isn't a 32-bit float... -
Ilya Kobelevskiy over 10 years@MatsPetersson - I just want to ensure that float is 32 bit, and not 64 or 16 bit.
-
Mats Petersson over 10 yearsSo, are you writing code that is likely to run on really obscure hardware? I mean DSP's and large and ancient mainframes? If not, then I'd say ignore the problem... [I have a feeling that QT won't work well on mainframes anyway, and DSP's tend to be pretty specialized].
-
MSalters over 10 yearsPointless. Even if you had two floats that are both 32 bits, they still would be incompatible when one has a 23 bits mantissa and the other a 25 bits mantissa. You would need to specify all widths, not just the total.
-
phuclv about 5 yearsPossible duplicate of Fixed-size floating point types
-
-
Martin R over 10 yearsAs far as I know,
sizeof()
cannot be used in a preprocessor directive. -
Admin over 10 years@MartinR why wouldn't it? it's compile-time anyway :p
-
Keith Thompson over 10 years@user9000: Because the preprocessor runs before the source code has even been parsed; the
sizeof
keyword is just an ordinary identifier with no special significance. -
Martin R over 10 yearsMy clang compiler complains: "error: token is not a valid binary operator in a preprocessor subexpression".
-
Mark Ransom over 10 years@MartinR I'm sure you're right. I'll update or delete this answer.
-
Void over 10 yearsThe desired affect can be achieved at compile-time with something like
typedef typename std::enable_if<sizeof(float)*CHAR_BIT == 32, float>::type float32;
, although you'd still have to handle the case whenfloat
is not 32 bits. -
Ilya Kobelevskiy over 10 yearsThanks! Is it certain Qt only runs on 32-bit IEEE? I tagged as C since I use qt but am not limited to it - any solution ensuring float is 32 bit/providing float data type guaranteed to be 32 bit would be fine, including C. I would like floating point to be 32 bit since I write 32bit since I do some pointer casts/arithmetic relying on the data sizes.
-
Keith Thompson over 10 years@IlyaKobelevskiy: It's not certain to me, and it's less certain that it will continue to be the case, but it's very likely. Consider not writing code that makes any assumptions about
sizeof (float)
. Otherwise, decide what you want to do if no 32-bit floating-point type is available. Unless you implement 32-bit FP in software (which is likely overkill), you're going to be out of luck -- and anassert
is just the way to handle that. -
peppe over 10 yearsYou can have compile time checks too -- C++ defines the macros
FLT_MIN
,FLT_MAX
,FLT_MANT_DIG
(#include <cfloat>
); or in C++11 code you can use astatic_assert(numeric_limits<float>::max() <= ...)
(or min, etc.) (#include <limits>
). -
Keith Thompson over 10 yearsAnd what about a platform where
float
is 32 bits, but with a different format than the one you want? It's difficult to tell just what your requirements are. -
bstamour over 10 yearsWhat about std::conditional? using float_type = typename std::conditional<sizeof(float) * CHAR_BIT == 32, float, float32>::type; EDIT: Nevermind. We are defining float32, not using it.
-
Adam Burry over 10 yearsOr, more simply, static_assert(sizeof(float) == 4, "require 32-bit floats").
-
MSalters over 10 years@Adam: Nope, that fails for CHAR_BIT==16.
-
MSalters over 10 years@IlyaKobelevskiy: Some low end ARMs have only
double
64 bits IEEE hardware. 32 bits FP can be fairly efficiently emulated in 64 bits., but you have issues similar to the x87 80 bits registers. -
Adam Burry over 10 years@MSalters, if I read you correctly, you are correct. What I wrote is true if a byte is not 8-bits. Since sizeof returns the number of bytes. Is that what you mean?
-
MSalters over 10 years@AdamBurry: Yes, C++ defines a
byte
as the size of achar
, which is not necessarily an octet (8 bits). Therefore,sizeof(char)==1
everywhere by definition. All other sizes are defined relative to this. -
Adam Burry over 10 years@MSalters, static_assert(sizeof(float) == 4 && CHAR_BIT == 8, "require 32-bit floats") Better?
-
Mark B over 10 years@Adam Burry That would preclude
sizeof(float) == 2 && CHAR_BIT == 16
though. -
Adam Burry over 10 years@MSalters, Have you seen such a system? I suppose if a propose (sizeof * CHAR_BIT) you will argue that static_assert is not portable to older compilers?
-
MSalters over 10 yearsWell, there is the obvious
static_assert(sizeof(float) * CHAR_BIT == 32, "require 32 bits floats"
which makes the 32 obvious and the code portable.