Difference between revisions of "cpp/language/floating literal"
D41D8CD98F (Talk | contribs) (expand {{spar|significand}}) |
m (~ fmt) |
||
(35 intermediate revisions by 14 users not shown) | |||
Line 1: | Line 1: | ||
− | {{title| | + | {{title|Floating-point literal}} |
{{cpp/language/expressions/navbar}} | {{cpp/language/expressions/navbar}} | ||
− | Floating point literal defines a compile-time constant whose value is specified in the source file. | + | Floating-point literal defines a compile-time constant whose value is specified in the source file. |
===Syntax=== | ===Syntax=== | ||
{{sdsc begin}} | {{sdsc begin}} | ||
− | {{sdsc |num=1| {{spar|digit-sequence}} {{spar|exponent}} {{spar|suffix}} | + | {{sdsc|num=1| {{spar|digit-sequence}} {{spar|decimal-exponent}} {{spar optional|suffix}}}} |
− | {{sdsc |num=2| {{spar|digit-sequence}} {{ttb|.}} {{spar|exponent}}{{ | + | {{sdsc|num=2| {{spar|digit-sequence}} {{ttb|.}} {{spar optional|decimal-exponent}} {{spar optional|suffix}}}} |
− | {{sdsc |num=3| {{spar|digit-sequence | + | {{sdsc|num=3| {{spar optional|digit-sequence}} {{ttb|.}} {{spar|digit-sequence}} {{spar optional|decimal-exponent}} {{spar optional|suffix}}}} |
− | {{sdsc |num=4|notes={{mark since c++17}}|{{ttb|0x}} {{!}} {{ttb|0X}} {{spar|hex-digit-sequence}} {{spar|exponent}} {{spar|suffix | + | {{sdsc|num=4|notes={{mark since c++17}}|{{ttb|0x}} {{!}} {{ttb|0X}} {{spar|hex-digit-sequence}} {{spar|hex-exponent}} {{spar optional|suffix}}}} |
− | {{sdsc |num=5|notes={{mark since c++17}}|{{ttb|0x}} {{!}} {{ttb|0X}} {{spar|hex-digit-sequence}} {{ttb|.}} {{spar|exponent}} {{spar|suffix | + | {{sdsc|num=5|notes={{mark since c++17}}|{{ttb|0x}} {{!}} {{ttb|0X}} {{spar|hex-digit-sequence}} {{ttb|.}} {{spar|hex-exponent}} {{spar optional|suffix}}}} |
− | {{sdsc |num=6|notes={{mark since c++17}}|{{ttb|0x}} {{!}} {{ttb|0X}} {{spar|hex-digit-sequence | + | {{sdsc|num=6|notes={{mark since c++17}}|{{ttb|0x}} {{!}} {{ttb|0X}} {{spar optional|hex-digit-sequence}} {{ttb|.}} {{spar|hex-digit-sequence}} {{spar|hex-exponent}} {{spar optional|suffix}}}} |
{{sdsc end}} | {{sdsc end}} | ||
− | @1@ {{spar|digit-sequence}} representing a whole number without a decimal separator, in this case the exponent is not optional: {{c|1e10}}, {{c|1e-5L}} | + | @1@ {{spar|digit-sequence}} representing a whole number without a decimal separator, in this case the exponent is not optional: {{c|1e10}}, {{c|1e-5L}}. |
− | @2@ {{spar|digit-sequence}} representing a whole number with a decimal separator, in this case the exponent is optional: {{c|1.}}, {{c|1.e-2}} | + | @2@ {{spar|digit-sequence}} representing a whole number with a decimal separator, in this case the exponent is optional: {{c|1.}}, {{c|1.e-2}}. |
− | @3@ {{spar|digit-sequence}} representing a fractional number. The exponent is optional: {{c|3.14}}, {{c|.1f}}, {{c|0.1e-1L}} | + | @3@ {{spar|digit-sequence}} representing a fractional number. The exponent is optional: {{c|3.14}}, {{c|.1f}}, {{c|0.1e-1L}}. |
− | @4@ Hexadecimal {{spar|digit-sequence}} representing a whole number without a radix separator. The exponent is never optional for hexadecimal floating-point literals: {{c|0x1ffp10}}, {{c|0X0p-1}} | + | @4@ Hexadecimal {{spar|digit-sequence}} representing a whole number without a radix separator. The exponent is never optional for hexadecimal floating-point literals: {{c|0x1ffp10}}, {{c|0X0p-1}}. |
− | @5@ Hexadecimal {{spar|digit-sequence}} representing a whole number with a radix separator. The exponent is never optional for hexadecimal floating-point literals: {{c|0x1.p0}}, {{c|0xf.p-1}} | + | @5@ Hexadecimal {{spar|digit-sequence}} representing a whole number with a radix separator. The exponent is never optional for hexadecimal floating-point literals: {{c|0x1.p0}}, {{c|0xf.p-1}}. |
− | @6@ Hexadecimal {{spar|digit-sequence}} representing a fractional number with a radix separator. The exponent is never optional for hexadecimal floating-point literals: {{c|0x0.123p-1}}, | + | @6@ Hexadecimal {{spar|digit-sequence}} representing a fractional number with a radix separator. The exponent is never optional for hexadecimal floating-point literals: {{c|0x0.123p-1}}, {{c|0xa.bp10l}}. |
− | + | {{spar|decimal-exponent}} has the form | |
{{sdsc begin}} | {{sdsc begin}} | ||
− | {{sdsc | + | {{sdsc|{{ttb|e}} {{!}} {{ttb|E}} {{spar optional|exponent-sign}} {{spar|digit-sequence}}}} |
− | {{sdsc | + | {{sdsc end}} |
+ | |||
+ | {{spar|hex-exponent}} has the form | ||
+ | {{sdsc begin}} | ||
+ | {{sdsc|{{ttb|p}} {{!}} {{ttb|P}} {{spar optional|exponent-sign}} {{spar|digit-sequence}}|notes={{mark since c++17}}}} | ||
{{sdsc end}} | {{sdsc end}} | ||
− | |||
− | |||
{{spar|exponent-sign}}, if present, is either {{ttb|+}} or {{ttb|-}} | {{spar|exponent-sign}}, if present, is either {{ttb|+}} or {{ttb|-}} | ||
− | {{spar|suffix}}, if present, is one of {{ttb|f}}, {{ttb| | + | {{spar|suffix}}, if present, is one of {{ttb|f}}, {{ttb|l}}, {{ttb|F}}, {{ttb|L}}{{rev inl|since=c++23|, {{ttb|f16}}, {{ttb|f32}}, {{ttb|f64}}, {{ttb|f128}}, {{ttb|bf16}}, {{ttb|F16}}, {{ttb|F32}}, {{ttb|F64}}, {{ttb|F128}}, {{ttb|BF16}}}}. The suffix determines the type of the floating-point literal: |
− | :* (no suffix) defines {{c|double}} | + | :* (no suffix) defines {{c/core|double}} |
− | :* {{ttb|f F}} defines {{c|float}} | + | :* {{ttb|f F}} defines {{c/core|float}} |
− | :* {{ttb|l L}} defines {{c|long double}} | + | :* {{ttb|l L}} defines {{c/core|long double}} |
+ | {{rrev|since=c++23| | ||
+ | :* {{ttb|f16 F16}} defines {{lc|std::float16_t}} | ||
+ | :* {{ttb|f32 F32}} defines {{lc|std::float32_t}} | ||
+ | :* {{ttb|f64 F64}} defines {{lc|std::float64_t}} | ||
+ | :* {{ttb|f128 F128}} defines {{lc|std::float128_t}} | ||
+ | :* {{ttb|bf16 BF16}} defines {{lc|std::bfloat16_t}} | ||
+ | }} | ||
− | {{ | + | {{anchor|Single quote}} |
− | {{ | + | {{rrev|since=c++14| |
− | + | Optional single quotes ({{c/core|'}}) may be inserted between the digits as a separator; they are ignored when determining the value of the literal. | |
+ | }} | ||
===Explanation=== | ===Explanation=== | ||
− | Decimal scientific notation is used, meaning that the value of the floating-point literal is the significand | + | Decimal scientific notation is used, meaning that the value of the floating-point literal is the significand multiplied by the number 10 raised to the power of {{spar|decimal-exponent}}. E.g. the mathematical meaning of {{c|123e4}} is ''123×10<sup>4</sup>''. |
− | {{ | + | {{rrev|since=c++17| |
− | + | ||
If the floating literal begins with the character sequence {{tt|0x}} or {{tt|0X}}, the floating literal is a ''hexadecimal floating literal''. Otherwise, it is a ''decimal floating literal''. | If the floating literal begins with the character sequence {{tt|0x}} or {{tt|0X}}, the floating literal is a ''hexadecimal floating literal''. Otherwise, it is a ''decimal floating literal''. | ||
− | For a ''hexadecimal floating literal'', the significand is interpreted as a hexadecimal rational number, and the {{spar|digit-sequence}} of the exponent is interpreted as the integer power of 2 | + | For a ''hexadecimal floating literal'', the significand is interpreted as a hexadecimal rational number, and the {{spar|digit-sequence}} of the exponent is interpreted as the (decimal) integer power of 2 by which the significand has to be scaled. |
− | {{ | + | |
− | double d = 0x1. | + | {{cc|1=double d = 0x1.4p3;}}{{tt|// hex fraction 1.4 (decimal 1.25) scaled by 2{{sup|3}}, that is 10.0}} |
− | }} | + | |
}} | }} | ||
− | {{ | + | |
+ | ===Notes=== | ||
+ | The hexadecimal floating-point literals were not part of C++ until C++17, although they can be parsed and printed by the I/O functions since C++11: both C++ I/O streams when {{lc|std::hexfloat}} is enabled and the C I/O streams: {{lc|std::printf}}, {{lc|std::scanf}}, etc. See {{lc|std::strtof}} for the format description. | ||
+ | |||
+ | {{feature test macro|value=201603L|std=C++17|__cpp_hex_float|Hexadecimal floating literals}} | ||
+ | |||
===Example=== | ===Example=== | ||
{{example|code= | {{example|code= | ||
+ | #include <iomanip> | ||
#include <iostream> | #include <iostream> | ||
+ | #include <limits> | ||
+ | #include <typeinfo> | ||
+ | |||
+ | #define OUT(x) '\n' << std::setw(16) << #x << x | ||
+ | |||
int main() | int main() | ||
{ | { | ||
− | + | std::cout | |
− | + | << "Literal" "\t" "Printed value" << std::left | |
− | + | << OUT( 58. ) // double | |
− | + | << OUT( 4e2 ) // double | |
+ | << OUT( 123.456e-67 ) // double | ||
+ | << OUT( 123.456e-67f ) // float, truncated to zero | ||
+ | << OUT( .1E4f ) // float | ||
+ | << OUT( 0x10.1p0 ) // double | ||
+ | << OUT( 0x1p5 ) // double | ||
+ | << OUT( 0x1e5 ) // integer literal, not floating-point | ||
+ | << OUT( 3.14'15'92 ) // double, single quotes ignored (C++14) | ||
+ | << OUT( 1.18e-4932l ) // long double | ||
+ | << std::setprecision(39) | ||
+ | << OUT( 3.4028234e38f ) // float | ||
+ | << OUT( 3.4028234e38 ) // double | ||
+ | << OUT( 3.4028234e38l ) // long double | ||
+ | << '\n'; | ||
+ | |||
+ | static_assert(3.4028234e38f == std::numeric_limits<float>::max()); | ||
+ | |||
+ | static_assert(3.4028234e38f == // ends with 4 | ||
+ | 3.4028235e38f); // ends with 5 | ||
+ | |||
+ | static_assert(3.4028234e38 != // ends with 4 | ||
+ | 3.4028235e38); // ends with 5 | ||
+ | |||
+ | // Both floating-point constants below are 3.4028234e38 | ||
+ | static_assert(3.4028234e38f != // a float (then promoted to double) | ||
+ | 3.4028234e38); // a double | ||
} | } | ||
+ | |p=true | ||
|output= | |output= | ||
− | 1.23456e-65 | + | Literal Printed value |
− | 1000 | + | 58. 58 |
− | + | 4e2 400 | |
− | + | 123.456e-67 1.23456e-65 | |
+ | 123.456e-67f 0 | ||
+ | .1E4f 1000 | ||
+ | 0x10.1p0 16.0625 | ||
+ | 0x1p5 32 | ||
+ | 0x1e5 485 | ||
+ | 3.14'15'92 3.14159 | ||
+ | 1.18e-4932l 1.18e-4932 | ||
+ | 3.4028234e38f 340282346638528859811704183484516925440 | ||
+ | 3.4028234e38 340282339999999992395853996843190976512 | ||
+ | 3.4028234e38l 340282339999999999995912555211526242304 | ||
}} | }} | ||
− | === | + | ===References=== |
− | + | {{ref std c++23}} | |
+ | {{ref std| section = 5.13.4| title=Floating-point literals| id= lex.fcon}} | ||
+ | {{ref std end}} | ||
+ | {{ref std c++20}} | ||
+ | {{ref std| section = 5.13.4| title=Floating-point literals| id= lex.fcon}} | ||
+ | {{ref std end}} | ||
+ | {{ref std c++17}} | ||
+ | {{ref std| section = 5.13.4| title=Floating literals| id= lex.fcon}} | ||
+ | {{ref std end}} | ||
+ | {{ref std c++14}} | ||
+ | {{ref std| section = 2.14.4| title=Floating literals| id= lex.fcon}} | ||
+ | {{ref std end}} | ||
+ | {{ref std c++11}} | ||
+ | {{ref std| section = 2.14.4| title=Floating literals| id= lex.fcon}} | ||
+ | {{ref std end}} | ||
+ | <!--{{ref std c++03}} | ||
+ | {{ref std| section = 2.13.3| title=Floating literals| id= lex.fcon}} | ||
+ | {{ref std end}}N1804--> | ||
+ | {{ref std c++98}} | ||
+ | {{ref std| section = 2.13.3| title=Floating literals| id= lex.fcon}} | ||
+ | {{ref std end}} | ||
===See also=== | ===See also=== | ||
{{dsc begin}} | {{dsc begin}} | ||
− | {{dsc see c | c/language/floating_constant | | + | {{dsc inc|cpp/language/dsc user_literal}} |
+ | {{dsc see c|c/language/floating_constant|Floating constant|nomono=true}} | ||
{{dsc end}} | {{dsc end}} | ||
− | + | {{langlinks|de|es|fr|it|ja|pt|ru|zh}} | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + |
Latest revision as of 03:33, 26 September 2024
Floating-point literal defines a compile-time constant whose value is specified in the source file.
Contents |
[edit] Syntax
digit-sequence decimal-exponent suffix (optional) | (1) | ||||||||
digit-sequence . decimal-exponent (optional) suffix (optional)
|
(2) | ||||||||
digit-sequence (optional) . digit-sequence decimal-exponent (optional) suffix (optional)
|
(3) | ||||||||
0x | 0X hex-digit-sequence hex-exponent suffix (optional)
|
(4) | (since C++17) | |||||||
0x | 0X hex-digit-sequence . hex-exponent suffix (optional)
|
(5) | (since C++17) | |||||||
0x | 0X hex-digit-sequence (optional) . hex-digit-sequence hex-exponent suffix (optional)
|
(6) | (since C++17) | |||||||
decimal-exponent has the form
e | E exponent-sign (optional) digit-sequence
|
|||||||||
hex-exponent has the form
p | P exponent-sign (optional) digit-sequence
|
(since C++17) | ||||||||
exponent-sign, if present, is either +
or -
suffix, if present, is one of f
, l
, F
, L
, f16
, f32
, f64
, f128
, bf16
, F16
, F32
, F64
, F128
, BF16
(since C++23). The suffix determines the type of the floating-point literal:
- (no suffix) defines double
-
f F
defines float -
l L
defines long double
|
(since C++23) |
Optional single quotes (') may be inserted between the digits as a separator; they are ignored when determining the value of the literal. |
(since C++14) |
[edit] Explanation
Decimal scientific notation is used, meaning that the value of the floating-point literal is the significand multiplied by the number 10 raised to the power of decimal-exponent. E.g. the mathematical meaning of 123e4 is 123×104.
If the floating literal begins with the character sequence For a hexadecimal floating literal, the significand is interpreted as a hexadecimal rational number, and the digit-sequence of the exponent is interpreted as the (decimal) integer power of 2 by which the significand has to be scaled. double d = 0x1.4p3; |
(since C++17) |
[edit] Notes
The hexadecimal floating-point literals were not part of C++ until C++17, although they can be parsed and printed by the I/O functions since C++11: both C++ I/O streams when std::hexfloat is enabled and the C I/O streams: std::printf, std::scanf, etc. See std::strtof for the format description.
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_hex_float |
201603L | (C++17) | Hexadecimal floating literals |
[edit] Example
#include <iomanip> #include <iostream> #include <limits> #include <typeinfo> #define OUT(x) '\n' << std::setw(16) << #x << x int main() { std::cout << "Literal" "\t" "Printed value" << std::left << OUT( 58. ) // double << OUT( 4e2 ) // double << OUT( 123.456e-67 ) // double << OUT( 123.456e-67f ) // float, truncated to zero << OUT( .1E4f ) // float << OUT( 0x10.1p0 ) // double << OUT( 0x1p5 ) // double << OUT( 0x1e5 ) // integer literal, not floating-point << OUT( 3.14'15'92 ) // double, single quotes ignored (C++14) << OUT( 1.18e-4932l ) // long double << std::setprecision(39) << OUT( 3.4028234e38f ) // float << OUT( 3.4028234e38 ) // double << OUT( 3.4028234e38l ) // long double << '\n'; static_assert(3.4028234e38f == std::numeric_limits<float>::max()); static_assert(3.4028234e38f == // ends with 4 3.4028235e38f); // ends with 5 static_assert(3.4028234e38 != // ends with 4 3.4028235e38); // ends with 5 // Both floating-point constants below are 3.4028234e38 static_assert(3.4028234e38f != // a float (then promoted to double) 3.4028234e38); // a double }
Possible output:
Literal Printed value 58. 58 4e2 400 123.456e-67 1.23456e-65 123.456e-67f 0 .1E4f 1000 0x10.1p0 16.0625 0x1p5 32 0x1e5 485 3.14'15'92 3.14159 1.18e-4932l 1.18e-4932 3.4028234e38f 340282346638528859811704183484516925440 3.4028234e38 340282339999999992395853996843190976512 3.4028234e38l 340282339999999999995912555211526242304
[edit] References
- C++23 standard (ISO/IEC 14882:2024):
- 5.13.4 Floating-point literals [lex.fcon]
- C++20 standard (ISO/IEC 14882:2020):
- 5.13.4 Floating-point literals [lex.fcon]
- C++17 standard (ISO/IEC 14882:2017):
- 5.13.4 Floating literals [lex.fcon]
- C++14 standard (ISO/IEC 14882:2014):
- 2.14.4 Floating literals [lex.fcon]
- C++11 standard (ISO/IEC 14882:2011):
- 2.14.4 Floating literals [lex.fcon]
- C++98 standard (ISO/IEC 14882:1998):
- 2.13.3 Floating literals [lex.fcon]
[edit] See also
user-defined literals(C++11) | literals with user-defined suffix |
C documentation for Floating constant
|