Exact Floating Point Compiler Parsing

As you know, IEEE floating point numbers can store exact representations of all integers and integer multiple inversions-of-powers-of-two, such as 1/2 or 3/4, since these numbers are stored within the floating point type range.

However, if floating point parsers, as a rule, guarantee the exact results of the analysis of decimal representations of such numbers?

For example, if I use 0.75 as a double literal in a C program, will the compiler guarantee that the compiled code contains the exact 3/4 representation, or is there a risk that it will create the sum of some inaccurate representation of 0.7 and some inaccurate representation of 0, 05?

Or, if I use 3e4 as a double literal, is it possible to accurately multiply 3 by some inaccurate representation of 2 ^ (4 * ln (10) / ln (2)) or some similar math

Are there any standards that FP parsers usually need to follow in this matter, or is it usually completely implementation related? If this is the latter, does anyone know how practically important implementations like GCC or glibc actually work?

Basically, I just ask for curiosity, and not because I want to rely on behavior; but sometimes it can be quite convenient to know that comparisons of FP equalities are guaranteed to work if the values ​​can only be known from literals.

+4
source share
2 answers

The C standard allows a floating point constant to be either the representable value closest to the exact value of the literal constants, or a larger or smaller representable value immediately adjacent to the closest value, for C 2011 6.4.4.2 3. Some C implementations are better. Modern implementations should improve as algorithms for proper conversion are published.

However, the C standard also provides hexadecimal floating point constants, which makes it easier for the compiler to correctly convert. The hexadecimal floating-point constant has the basic form: 0x hhh . hhh p eee , where hhh are hexadecimal digits and eee is the decimal value that may have a sign. (Hexadecimal digits on one side. "" Can be omitted if they are zero, and the period can be omitted if the digits on the right are omitted.) Index for degree two.

Standard C requires that the hexadecimal floating-point constant be correctly rounded if the radius for floating-point numbers is 2 in implementation C. He recommends creating a diagnostic message if the hexadecimal constant cannot be represented accurately.

For example, 0x3p-2 must be exactly .75.

+4
source

As a rule, there is no guarantee that the nearest floating-point number in the abstract syntax tree is up to the decimal representation in the source code. A language standard, such as C99, may indicate that it should be within the same ULP (i.e. not the closest, but one of the two closest). In practice, the compiler can use the host functions strtof() , strtod() , ..., which again are not specified as returning the closest number, and indeed sometimes not ).

A limitation within ULP implies that the exact decimal representation of a floating point number must be converted to that number. However, many interpreters, such as Ruby or Tcl, have their own strtod() if the host does not. This implementation is terrible and can return a result that is incorrect by several ULPs.

If you need to solve this problem by implementing your own conversion function, a diagram of a simple but correct function based on large integers can be found on the Binary Learning Blog .


To summarize: for a language that defines a decimal to floating-point conversion to a single ULP, you should be fine for accurate representations if you use a quality compiler implementation. For interpreted languages ​​without such a specification, either the strtod() host is called, in which case you should fine, or use a terrible implementation, in which case you are not.

+2
source

All Articles