ISO/IEC JTC1 SC22 WG21 P00245r1

Date: 2016年03月04日

To: EWG, CWG

Thomas Köppe <tkoeppe@google.com>

Hexadecimal floating literals for C++

Contents

  1. Revision history
  2. Summary
  3. Impact
  4. Proposed wording
  5. An iostreams issue
  6. Existing practice and implementation experience

Revision history

P0245r0: Initial proposal.

Changes from P0245r0 to P0245r1:

Summary

There is a base-2 scientific notation for floating point values: 0x3.ABCp-10. The significand is given in hexadecimal, and the exponent is given in decimal and interpreted with respect to base 2. This notation is convenient for certain uses. For example, the smallest normal IEEE-754 single precision value is readily written as 0x1.0p-126. More generally, this notation can be used when an exact object representation is desired (and the floating point implementation uses a base-2 or base-2n representation).

The standard library outputs this representation via the hexfloat manipulator for ostreams, and via the a/A conversion specifiers in printf. Similarly, formatted input works because strtod recognises this representation (and the semantics of formatted istream input operations and scanf are defined in terms of strtod, but see below for a detail). We should also allow this representation as a literal in the core language.

Note that the C language which is referenced by the C++ standard also allows this literal syntax.

Impact

This is a core language extension that adds a new numeric literal syntax. The proposed syntax is ill-formed in the current working draft. Note that non-standard user-defined literals must start with an underscore, and the standard library does not define a UDL operator named p or P.

Proposed wording

In section [lex.fcon] (2.13.4 in the working draft), change the grammar as follows (cf. C11 6.4.4.2/1).

floating-literal: (追記) decimal-floating-literal (追記ここまで) (追記) hexadecimal-floating-literal (追記ここまで) (追記) decimal-floating-literal: (追記ここまで) fractional-constant exponent-partopt floating-suffixopt digit-sequence exponent-part floating-suffixopt (追記) hexadecimal-floating-literal: (追記ここまで) (追記) hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part floating-suffixopt (追記ここまで) (追記) hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part floating-suffixopt (追記ここまで) fractional-constant: digit-sequenceopt . digit-sequence digit-sequence . (追記) hexadecimal-fraction-constant: (追記ここまで) (追記) hexadecimal-digit-sequenceopt . hexadecimal-digit-sequence (追記ここまで) (追記) hexadecimal-digit-sequence . (追記ここまで) exponent-part: e signopt digit-sequence E signopt digit-sequence (追記) binary-exponent-part: (追記ここまで) (追記) p signopt digit-sequence (追記ここまで) (追記) P signopt digit-sequence (追記ここまで) sign: one of + - digit-sequence: digit digit-sequence 'opt digit (追記) hexadecimal-digit-sequence: (追記ここまで) (追記) hexadecimal-digit (追記ここまで) (追記) hexadecimal-digit-sequence 'opt hexadecimal-digit (追記ここまで) (追記) hexadecimal-prefix: one of (追記ここまで) (追記) 0x 0X (追記ここまで) floating-suffix: one of f l F L

Change the subsequent paragraph 1 in the following way:

A floating literal consists of (追記) an optional prefix specifying a base, (追記ここまで) an integer part, a (削除) decimal (削除ここまで)(追記) radix (追記ここまで) point, a fraction part, an (削除) e or E, (削除ここまで) (追記) e, E, p or P, (追記ここまで) an optionally signed integer exponent, and an optional type suffix. The integer and fraction parts both consist of a sequence of decimal (base ten) digits (削除) . (削除ここまで)(追記) if there is no prefix, or hexadecimal (base sixteen) digits if the prefix is 0x or 0X. The literal is a decimal floating literal in the former case and a hexadecimal floating literal in the latter case. (追記ここまで) Optional separating single quotes in a digit-sequence (追記) or hexadecimal-digit-sequence (追記ここまで) are ignored when determining its value. [Example. The literals 1.602'176'565e-19 and 1.602176565e-19 have the same value. – end example] Either the integer part or the fraction part (not both) can be omitted(削除) ; either (削除ここまで)(追記) . Either (追記ここまで) the (削除) decimal (削除ここまで)(追記) radix (追記ここまで) point or the letter e (削除) (or E ) (削除ここまで)(追記) or E (追記ここまで) and the exponent (not both) can be omitted (追記) from a decimal floating literal (追記ここまで). (追記) The radix point (but not the exponent) can be omitted from a hexadecimal floating literal. (追記ここまで) The integer part, the optional (削除) decimal (削除ここまで)(追記) radix (追記ここまで) point and the optional fraction part form the (削除) significant part (削除ここまで)(追記) significand (追記ここまで) of the floating literal. (削除) The (削除ここまで)(追記) In a decimal floating literal, the (追記ここまで) exponent, if present, indicates the power of 10 by which the (削除) significant part (削除ここまで)(追記) significand (追記ここまで) is to be scaled. (追記) In a hexadecimal floating literal, the exponent indicates the power of 2 by which the significand is to be scaled. [Example. The literals 49.625 and 0xC.68p+2 have the same value. – end example] (追記ここまで) If the scaled value is in the range of representable values for its type, the result is the scaled value if representable, else the larger or smaller representable value nearest the scaled value, chosen in an implementation-defined manner. The type of a floating literal is double unless explicitly specified by a suffix. The suffixes f and F specify float, the suffixes l and L specify long double. If the scaled value is not in the range of representable values for its type, the program is ill-formed.

Drafting note. We changed “significant part” to “significand” and “decimal point” to “radix point”.

Also change the grammar in section [lex.ext] (2.13.8):

user-defined-floating-literal: fractional-constant exponent-partopt ud-suffix digit-sequence exponent-part ud-suffix (追記) hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part ud-suffix (追記ここまで) (追記) hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part ud-suffix (追記ここまで)

An iostreams issue

Although the library rules in [facet.num.get.members] say that formatted floating point input uses the conversion rules of strtod etc., the section also restricts the set of characters permissible for floating point parsing to "0123456789abcdefxABCDEFX+-", which is missing the values p and P. Should the present proposal succeed, we plan to either create a new library proposal, or revisit LWG issue 2381 to add support for parsing hexadecimal floating point literals to the standard library.

Existing practice and implementation experience

Hexadecimal float literals are already supported as a vendor extension by several compilers: Clang, EDG, Embarcadero, GCC. Formatted input via iostreams is supported by libc++.

AltStyle によって変換されたページ (->オリジナル) /