Floating-point literals are decomposed by type in order to preserve type information gleaned during lexical analysis. If this information were not preserved, later components of the compiler would be forced to re-scan the characters of the literal to obtain it.

A floating-point literal has the following parts:
a whole-number part,
a decimal point,
a fractional part,
an exponent,
and a type suffix.
The exponent, if present, is indicated by the letter `e` or `E`
followed by an optionally signed integer.

At least one digit, in either the whole number or the fractional part, and either a decimal point, an exponent, or a float type suffix are required. All other parts are optional.

DoubleLiteral: $((

FloatLiteral: $(

This macro is invoked in definition 12.

The `D` macro represents a single digit:

The `N` macro represents a sequence of digits with a leading, trailing or
embedded decimal point:

This macro is invoked in definition 20.

The `E` macro represents an exponent:

This macro is invoked in definition 20.

The grammar symbol `FloatingPointLiteral` is expanded to retain the type
information:

This macro is invoked in definition 39.

The token processor `mkflt` converts the value to IEEE 754 format,
expressed as a character string.
Thus if `i` is the internal representation of a floating point literal,
`StringTable(i)` is always in normalized IEEE 754 format.
Digits of single-precision values are binary, those of double-precision
values are hexadecimal.
Exponents are always sequences of decimal digits.

{ char save, *temp; int DomainError;

/* If there is a type specifier on the end, remove it since we don't */

/* need it anymore. */

if (*t == FloatLiteral || c[l-1] == 'd' || c[l-1] == 'D') l-;

(void)strmath(STRM_EXP_SYMBOLS, "eE");

(void)strmath(STRM_INTEGER_SIZE, 1);

(void)strmath(STRM_ROUND_SIZE, ARITH_SIZE-1);

save = c[l]; c[l] = '\0';

if (*t == FloatLiteral) {

} else {

}

c[l] = save;

(void)strmath(STRM_ROUND_SIZE, 0);

(void)strmath(STRM_INTEGER_SIZE, ARITH_SIZE);

if (!CsmStrPtr || DomainError) {

message(ERROR, "Value out of range", 0, &curpos);

obstack_free(Csm_obstk, CsmStrPtr); *s = 0; return;

}

mkidn(CsmStrPtr, strlen(CsmStrPtr), t, s);

}

If an overflow is detected, the internal representation is set to `0`.
`StringTable[0]` is the internal representation of a null string, and is
therefore different from the representation of any valid number.

A `FloatingPointLiteral` is regarded as representing an exact decimal value
in the usual ``computerized scientific notation''.

temp = strnorm(c, 10, 10, "e");

CsmStrPtr = obstack_copy0(Csm_obstk, temp, strlen(temp));

This macro is invoked in definition 25.

Overflow is detected by subtracting the converted value from the maximum possible value; underflow is detected by subtracting the minimum possible value from the converted value. In both cases, a negative value represents the error condition. The constants for minimum and maximum values for float and double are taken from section 3.10.2 of the language specification.

temp = strsub("3.40282347e38", CsmStrPtr, 10);

DomainError = (!temp || temp[0] == '-');

if (CsmStrPtr[0] != '0') {

/*

* Fib on this one, since the JDK appears to have a smaller MIN_VALUE.

* temp = strsub(CsmStrPtr, "1.40239846e-45", 10);

*/

temp = strsub(CsmStrPtr, "1.40129846432481707e-45", 10);

DomainError |= (!temp || temp[0] == '-');

}

This macro is invoked in definition 25.

temp = strsub("1.79769313486231570e308", CsmStrPtr, 10);

DomainError = (!temp || temp[0] == '-');

if (CsmStrPtr[0] != '0') {

temp = strsub(CsmStrPtr, "4.94065645841246544e-324", 10);

DomainError |= (!temp || temp[0] == '-');

}

This macro is invoked in definition 25.