Originally posted as TotW #175 on January 30, 2020
“The only thing that stays the same is change” – Melissa Etheridge
C++ now has some features that can make numeric literals more readable.
Integer literals can now be written in binary (
0b00101010) as well as the
42), hex (
0x2A), and octal (
052) formats that have been supported
since the dawn of time.
Single quotes (
') serve as digit separators, and can be used to group digits
in numeric literals of any base (
Floating point literals can be specified in hex (
Binary literals such as
0b1110'0000 can be more readable than hex (the next
best option) when manipulating bit sets or working with low-level protocols.
Code that does these things should be rare in google3, where a higher-level
technique is usually a better choice.
C++14 allows a single quote (
') to be used to group digits in a numeric
literal. These digit separators have no effect on the value of the constant:
their only function is to help readers. They can make it easy to see at a glance
how many digits are present, and know that none are missing. For example,
1'000'000'000 is more obviously one billion than is
1000000000 (and unlike
1e9 it is an integer, not a floating point value).
There are no restrictions on the number of digits per group, not even a
requirement of consistency within a literal:
0b1'001'0001 is a valid way to
write the number 145 (and may even make sense for a byte that is interpreted as
three separate fields).
While most decimal floating point literals are not exactly representable in the binary floating point formats used by most computers, hex floating literals do map directly to bit patterns in floating point so long as enough bits are available. This avoids rounding errors when converting a literal to floating point format (though truncation errors are still possible if too many hex digits are present).
Hex floating point literals are indicated by writing a
P) to separate
the significand from the exponent—where decimal floating point literals would
E). For example,
0x2Ap12 is another way to write the value
<< 12, i.e., 0x2A000. The exponent is always written in decimal, denotes a
power of 2, and may be negative:
0x1p-10 is (exactly)