r/cpp•
1Bad

Why do we have int(N)_t, but no equivalent for floating point?

I am curious why we have int8_t, int16_t, etc... but don't have explicit size types for floating point? e.g. float32_t, float64_t, float80_t

Posted Apr 30, 2015, 5:08 AM UTC

616
ggchappell•

I think the reason is that we know exactly what an int32_t is: 32 bits representing an integer value in a specific way; endianness may differ, but that's it.

But what is a float32_t? Yes, it's 32 bits. Now, how many of these are devoted to the mantissa and the exponent? Does the representation even use the sign-exponent-mantissa format? Are there special values for not-a-number or infinity? How are these represented?

So float32_t is a rather hazier concept than int32_t.

Nonetheless, a proposal has been submitted to both the C and the C++ standardization committees to add a new header to the Standard Libraries with typedefs just like those you are talking about.

The general feeling on the C++ end of things is that C should lead in these matters, and C++ will follow. But the C committee does not seem to be doing anything about it, as far as I can tell.

21
1BadOP•

Neat, thanks for pointing out the proposal. It explains support on different platforms, and other things I was interested about.

3
boredcircuits•

I'll take a guess here.

For floating point, the number of bits doesn't tell you much. What you really want to know is the precision, range, etc. All the number of bits gives you is the storage space.

That, and there's like 8 internet types to deal with, all different on common platforms, while must floating point types are pretty consistent.

10
AntiProtonBoy•

For floating point, the number of bits doesn't tell you much. What you really want to know is the precision, range, etc. All the number of bits gives you is the storage space.

I would argue that when adding float##_t types in the C/C++ standard, one could also mandate the binary representations to conform with the IEEE 754 specification. That takes out the ambiguity regarding range, precision and so forth. However, the immediate downside is that some platforms might not benefit from this, as the underlying hardware does not conform with IEEE 754 natively.

Perhaps something like this would make more sense:

std::ieee754::float16_t
std::ieee754::float32_t
std::ieee754::float64_t
std::ieee754::float80_t
std::ieee754::float128_t
12
vlovich•

It would be extremely helpful for scientific experiments if there were an IEEE type. On machines where it wasn't natively supported you would have the compiler generate function calls to a math library that emulated IEEE.

I still think you would need numeric_limits to expose if the IEEE754 representation was natively supported so that you could have a type like best_native_float_t that represented the best available on the hardware natively.

That being said, I don't know if there's actually any hardware out there that's fully IEEE compliant. There's a lot of nuance particularly around denormalized numbers that most implementations used to ignore (don't know if they still do).

4
smikims•

I think the IEEE 754 idea is the best, since the all of the int##_t types aren't natively supported on many platforms either (e.g. 64-bit types on many architectures), and it guarantees consistency.

1
ChrisSharpe•

internet types?

6
boredcircuits•

Sorry, no compiler on mobile to check for typos.

4
1BadOP•

That makes sense, if not all hardware types can guarantee support for a specific floating point format (thus the standard can't mandate a format) then the size isn't so important. I don't know if the standard mandates a floating point format or not, or what the state of hardware support is.

1
milesrout•

I think there should be std::ieee754_float32_t and std::ieee754_float64_t at least, which would be REQUIRED to be 100% fully compliant with IEEE754 with all the various floating point state manipulation, rounding modes, etc. enabled.

If the target platform doesn't support this natively then the compiler could do what it does if it doesn't support, say, 64-bit arithmetic natively: use library code.

Then you could have std::fast_float_t which would be the fastest possible floating point type on the machine, probably single-precision on most machines I expect. You could have std::fast_float32_t which would be the fastest 32-bit floating point i.e. the native 32-bit float type, even if it isn't IEEE754 floating point.

7
minno•

AFAIK float and double have the same width on every platform, but int, short, and long don't. So there's a need for int32_t, but not float32_t.

3†
cleroth•

The standard doesn't mandate that. It doesn't specify anything related to their size, only that double cannot have a precision less than float, and that a long double cannot have a precision less than a double.

7
boredcircuits•

Unfortunately, that's not true for some embedded platforms. On the Arduino, a double is exactly the same as a float.

4
1BadOP•

So cppreference is wrong? I thought double and long double were usually the same but float and double were usually different.

float - single precision floating point type. Usually IEEE-754 32 bit floating point type

double - double precision floating point type. Usually IEEE-754 64 bit floating point type

long double - extended precision floating point type. Does not necessarily map to types mandated by IEEE-754. Usually 80-bit x87 floating point type on x86 and x86-64 architectures.

1
minno•

I didn't quite phrase that right. I meant that on any two platforms, float will have the same width on both platforms, and so will double. Not that sizeof(float) == sizeof(double).

7
milesrout•

On amd64, on Linux, using GCC, IIRC, float is 32-bit, double is 64-bit and long double is 80-bit.

2