Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/language/floating literal"

From cppreference.com
< cpp‎ | language
m (~ fmt)
 
(21 intermediate revisions by 7 users not shown)
Line 6: Line 6:
 
===Syntax===
 
===Syntax===
 
{{sdsc begin}}
 
{{sdsc begin}}
{{sdsc |num=1| {{spar|digit-sequence}} {{spar|decimal-exponent}} {{spar|suffix}}{{mark optional}}  }}
+
{{sdsc|num=1| {{spar|digit-sequence}} {{spar|decimal-exponent}} {{spar optional|suffix}}}}
{{sdsc |num=2| {{spar|digit-sequence}} {{ttb|.}} {{spar|decimal-exponent}}{{mark optional}} {{spar|suffix}}{{mark optional}}  }}
+
{{sdsc|num=2| {{spar|digit-sequence}} {{ttb|.}} {{spar optional|decimal-exponent}} {{spar optional|suffix}}}}
{{sdsc |num=3| {{spar|digit-sequence}}{{mark optional}} {{ttb|.}} {{spar|digit-sequence}} {{spar|decimal-exponent}}{{mark optional}} {{spar|suffix}}{{mark optional}}  }}
+
{{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|hex-exponent}} {{spar|suffix}}{{mark optional}} }}
+
{{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|hex-exponent}} {{spar|suffix}}{{mark optional}} }}
+
{{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}}{{mark optional}} {{ttb|.}} {{spar|hex-digit-sequence}} {{spar|hex-exponent}} {{spar|suffix}}{{mark optional}}  }}
+
{{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}}, {{c|0xa.bp10l}}
+
@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
 
{{spar|decimal-exponent}} has the form
 
{{sdsc begin}}
 
{{sdsc begin}}
{{sdsc|{{ttb|e}} {{!}} {{ttb|E}} {{spar|exponent-sign}}{{mark optional}} {{spar|digit-sequence}}}}
+
{{sdsc|{{ttb|e}} {{!}} {{ttb|E}} {{spar optional|exponent-sign}} {{spar|digit-sequence}}}}
 
{{sdsc end}}
 
{{sdsc end}}
  
 
{{spar|hex-exponent}} has the form
 
{{spar|hex-exponent}} has the form
 
{{sdsc begin}}
 
{{sdsc begin}}
{{sdsc|{{ttb|p}} {{!}} {{ttb|P}} {{spar|exponent-sign}}{{mark optional}} {{spar|digit-sequence}}|notes={{mark since c++17}}}}
+
{{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|F}}, {{ttb|l}}, or {{ttb|L}}. The suffix determines the type of the floating-point literal:
+
{{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}}
 +
}}
  
{{rrev | since = c++14 |
+
{{anchor|Single quote}}
Optional single quotes ({{tt|'}}) may be inserted between the digits as a separator; they are ignored during compilation.
+
{{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.
 
}}
 
}}
  
Line 47: Line 55:
 
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 to which the significand has to be scaled.
+
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.
{{source|1=
+
 
double d = 0x1.4p3; // hex fraction 1.4 (decimal 1.25) scaled by 2^3, that is 10.0
+
{{cc|1=double d = 0x1.4p3;}}{{tt|// hex fraction 1.4 (decimal 1.25) scaled by 2{{sup|3}}, that is 10.0}}
}}
+
 
}}
 
}}
  
 
===Notes===
 
===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 {{c|std::hexfloat}} is enabled and the C I/O streams: {{c|std::printf}}, {{c|std::scanf}}, etc. See {{c|std::strtof}} for the format description  
+
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 << 58.         << '\n'
+
    std::cout
            << 4e2         << '\n'
+
         << "Literal" "\t" "Printed value" << std::left
            << 123.456e-67 << '\n'
+
        << OUT( 58.            ) // double
            << .1E4f      << '\n'
+
         << OUT( 4e2            ) // double
            << 0x10.1p0   << '\n'
+
        << OUT( 123.456e-67   ) // double
            << 0x1e5      << '\n'; // integer literal, not floating-point literal
+
        << 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=
58
+
Literal        Printed value
400
+
58.            58
1.23456e-65
+
4e2            400
1000
+
123.456e-67    1.23456e-65
16.0625
+
123.456e-67f    0
485
+
.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 inc | cpp/language/dsc user_literal}}
+
{{dsc inc|cpp/language/dsc user_literal}}
{{dsc see c | c/language/floating_constant | Floating constant | nomono=true}}
+
{{dsc see c|c/language/floating_constant|Floating constant|nomono=true}}
 
{{dsc end}}
 
{{dsc end}}
  
 
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}
 
{{langlinks|de|es|fr|it|ja|pt|ru|zh}}

Latest revision as of 03:33, 26 September 2024

 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

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)
1) digit-sequence representing a whole number without a decimal separator, in this case the exponent is not optional: 1e10, 1e-5L.
2) digit-sequence representing a whole number with a decimal separator, in this case the exponent is optional: 1., 1.e-2.
3) digit-sequence representing a fractional number. The exponent is optional: 3.14, .1f, 0.1e-1L.
4) Hexadecimal digit-sequence representing a whole number without a radix separator. The exponent is never optional for hexadecimal floating-point literals: 0x1ffp10, 0X0p-1.
5) Hexadecimal digit-sequence representing a whole number with a radix separator. The exponent is never optional for hexadecimal floating-point literals: 0x1.p0, 0xf.p-1.
6) Hexadecimal digit-sequence representing a fractional number with a radix separator. The exponent is never optional for hexadecimal floating-point literals: 0x0.123p-1, 0xa.bp10l.

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
  • f16 F16 defines std::float16_t
  • f32 F32 defines std::float32_t
  • f64 F64 defines std::float64_t
  • f128 F128 defines std::float128_t
  • bf16 BF16 defines std::bfloat16_t
(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 0x or 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 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;// hex fraction 1.4 (decimal 1.25) scaled by 23, that is 10.0

(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[edit]
C documentation for Floating constant