views:

774

answers:

3

In a C program, when you write a floating point literal like 3.14159 is there standard interpretation or is it compiler or architecture dependent? Java is exceedingly clear about how floating point strings are interpreted, but when I read K&R or other C documentation the issue seems swept under the rug.

+5  A: 

It is architecture dependent. That generally means IEEE 754, but not necessarily. The C standard (ISO 9899:1999) discusses this mainly in section 5.2.4.2.2 'Characteristics of floating types'.

Jonathan Leffler
Citation needed. I know this is true, but I can't find a resource which says so.
strager
The standard says so. It describes IEEE 754, but explicitly says that it is not required. It'd be in section 6.4.4.2 as noted by Adam Rosenfield, or 5.2.4.2.2 Characteristics of floating types.
Jonathan Leffler
+2  A: 

From the C99 standard, section 6.4.4.2 Floating constants, paragraph 3 (emphasis mine):

The significand part is interpreted as a (decimal or hexadecimal) rational number; the digit sequence in the exponent part is interpreted as a decimal integer. For decimal floating constants, the exponent indicates the power of 10 by which the significand part is to be scaled. For hexadecimal floating constants, the exponent indicates the power of 2 by which the significand part is to be scaled. For decimal floating constants, and also for hexadecimal floating constants when FLT_RADIX is not a power of 2, the result is either the nearest representable value, or the larger or smaller representable value immediately adjacent to the nearest representable value, chosen in an implementation-defined manner. For hexadecimal floating constants when FLT_RADIX is a power of 2, the result is correctly rounded.

So, you're going to get a constant within one ULP in an implementation-defined manner. Recall that implementation-defined means that the implementation (in this case, the C runtime) can choose any of the options, but that choice must be documented. So, you can consult libc runtime documentation to find out how the rounding occurs.

Adam Rosenfield
It's done by the runtime, not the compiler?
Nick
I think floating point constants are interpreted by the compiler, but the compiler must make every endeavour to ensure that its interpretation matches the runtime environment. This matters when cross-compiling; when compiling for the native machine, it is much easier.
Jonathan Leffler
Definitely the compiler. The runtime just sees the resulting machine code, unless you are using strings and sscanf/strtof or something similar.
HUAGHAGUAH
+1  A: 

You are not clear if you mean floating point literal as part of the source code (for the compiler to parse into architecture-dependent binary representation), or scanned by library functions, such as scanf(), atof(), strtol(), strtod() and strtold() (at run-time, to convert to in-memory float, double or long double value).

In the first case, it is part of ISO/IEC 9899:1999 (ISO C99), §6.4.4.2 "Floating constants". It defines both the lexicon and how it should be interpreted.

In the second case, the behavior of the library functions are defined in §7.20.1 "Numeric conversion functions".

I don't have a hard copy of the previous standard (ANSI C, 1989), but I'm pretty sure it also defines very precisely how floating point numbers are parsed and converted.

In the case you want to know if there is a standard to represent these values in binary format, in-memory, the answer is no. The C language is intended to be close to the architecture, and not impose constraints over it. So the in-memory representation is always architecture-dependent. But the C standard defines how arithmetic should be performed over floating point values. It follows IEC 60559 standard. In the ISO C99 standard, it is described in Annex F (normative), "IEC 60559 floating-point arithmetic". The implementation may or may not implement this standard. If it does, it must define the __STDC_IEC_559__ preprocessor name.

Juliano