next up previous
Next: Boolean Literals Up: Literals Previous: Integer Literals

Floating-Point Literals

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.

Floating-Point Literal[20]:

DoubleLiteral:  $((N[22]E[23]?|D[21]+E[23])[dD]?|D[21]+E[23]?[dD])  [mkflt]
FloatLiteral:   $(N[22]E[23]?[fF]?|D[21]+(E[23][fF]?|[fF]))     [mkflt]
This macro is invoked in definition 12.

The D macro represents a single digit:

D[21]:
[0-9]
This macro is invoked in definitions 20, 22, and 23.

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

N[22]:
(D[21]+\.D[21]*|\.D[21]+)
This macro is invoked in definition 20.

The E macro represents an exponent:

E[23]:
([eE][+-]?D[21]+)
This macro is invoked in definition 20.

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

FloatingPointLiteral[24]:
FloatLiteral / DoubleLiteral
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.

Normalize a literal value[25]:

Token processor[1](`mkflt')
{ 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';
  Convert a Floating-Point Literal[26]
  if (*t == FloatLiteral) {
    Check for over- or underflow in a FloatLiteral[27]
  } else {
    Check for over- or underflow in a DoubleLiteral[28]
  }
  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);
}
This macro is defined in definitions 18, 25, and 31.
This macro is invoked in definition 37.

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''.

Convert a Floating-Point Literal[26]:

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.

Check for over- or underflow in a FloatLiteral[27]:

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.

Check for over- or underflow in a DoubleLiteral[28]:

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.


next up previous
Next: Boolean Literals Up: Literals Previous: Integer Literals
2008-09-11