Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are there float and double types with fixed sizes in C99?

C99 states integer types like uint32_t, int16_t etc, where it's easy to see the number of bits used. Good to know in for instance embedded programming.

I have not found any similar types for floating point values. Is there a standard? If not, why?

like image 788
Fredrik Johansson Avatar asked Sep 08 '12 16:09

Fredrik Johansson


People also ask

Is float double or single?

float is a 32-bit IEEE 754 single precision Floating Point Number – 1 bit for the sign, 8 bits for the exponent, and 23* for the value. float has 7 decimal digits of precision.

Are floats and doubles interchangeable?

float is mostly used in graphic libraries for high processing power due to its small range. double is mostly used for calculations in programming to eliminate errors when decimal values are being rounded off. Although float can still be used, it should only be in cases when we're dealing with small decimal values.


2 Answers

I found the answer in Any guaranteed minimum sizes for types in C?

Quoting Jed Smith (with corrected link to C99 standard):

Yes, the values in float.h and limits.h are system dependent. You should never make assumptions about the width of a type, but the standard does lay down some minimums. See §6.2.5 and §5.2.4.2.1 in the C99 standard.

For example, the standard only says that a char should be large enough to hold every character in the execution character set. It doesn't say how wide it is.

For the floating-point case, the standard hints at the order in which the widths of the types are given:

§6.2.5.10

There are three real floating types, designated as float, double, and long double. 32) The set of values of the type float is a subset of the set of values of the type double; the set of values of the type double is a subset of the set of values of the type long double.

They implicitly defined which is wider than the other, but not specifically how wide they are. "Subset" itself is vague, because a long double can have the exact same range of a double and satisfy this clause.

This is pretty typical of how C goes, and a lot is left to each individual environment. You can't assume, you have to ask the compiler.

like image 191
Kwariz Avatar answered Sep 21 '22 09:09

Kwariz


To answer the "why" part of your question, the name uint32_t, for example, tells you everything you need to know about the type: it's unsigned and exactly 32 bits wide, which implies a range of exactly 0 to 4294967295. (The C standard requires that the uintN_t types have no padding bits or trap representations, and that the signed intN_t types use two's-complement.)

On the other hand, specifying the size in bits of a floating-point type doesn't tell you nearly as much. A hypothetical float64_t would be exactly 64 bits, but the bits that make up a floating-point object are divided into the sign bit, exponent, and significand (mantissa). Furthermore, the meaning of those bits can vary. In most representations, the exponent denotes a power of 2, but it can also be a power of 16. And there are numerous special representations: subnormals, denormals, NaNs, infinities, negative zero.

There are more variations in floating-point representations than can easily be encoded in a type name.

The IEEE floating-point standard (more properly IEC 60559) defines all this -- but if your implementation supports IEC 60559, then the C standard specifies the meanings of float and double anyway (though it allows some more flexibility for long double).

like image 29
Keith Thompson Avatar answered Sep 18 '22 09:09

Keith Thompson