浮点字面量

来自cppreference.com
< cpp‎ | language


 
 
C++ 语言
 
 

浮点字面量定义一种编译时常量,其值于源文件中指定。

语法

数字序列 十进制指数 后缀 (可选) (1)
数字序列 . 十进制指数 (可选) 后缀 (可选) (2)
数字序列 (可选) . 数字序列 十进制指数 (可选) 后缀 (可选) (3)
0x | 0X 十六进制数字序列 十六进制指数 后缀 (可选) (4) (C++17 起)
0x | 0X 十六进制数字序列 . 十六进制指数 后缀 (可选) (5) (C++17 起)
0x | 0X 十六进制数字序列 (可选) . 十六进制数字序列 十六进制指数 后缀 (可选) (6) (C++17 起)
1) 数字序列 表示无小数点的整数,此时指数不是可选的:1e101e-5L
2) 数字序列 表示带小数点的整数,此时指数是可选的:1.1.e-2
3) 数字序列 表示小数。指数是可选的:3.14.1f0.1e-1L
4) 十六进制 数字序列 表示无基底分隔符的整数。十六进制浮点字面量的指数总是必选的:0x1ffp100X0p-1
5) 十六进制 数字序列 表示带基底分隔符的整数。十六进制浮点字面量的指数总是必选的:0x1.p00xf.p-1
6) 十六进制 数字序列 表示带基底分隔符的小数。十六进制浮点字面量的指数总是必选的:0x0.123p-10xa.bp10l

十进制指数 拥有下列形式

e | E 指数正负号 (可选) 数字序列

十六进制指数 拥有下列形式

p | P 指数正负号 (可选) 数字序列 (C++17 起)

指数正负号 若存在则为 +-

后缀 若存在,则为 fFlLf16f32f64f128bf16F16F32F64F128BF16 (C++23 起) 之一。后缀决定浮点字面量的类型:

  • (无后缀)定义 double
  • f F 定义 float
  • l L 定义 long double
  • f16 F16 定义 std::float16_t
  • f32 F32 定义 std::float32_t
  • f64 F64 定义 std::float64_t
  • f128 F128 定义 std::float128_t
  • bf16 BF16 定义 std::bfloat16_t
(C++23 起)

数字间可插入作为分隔符的单引号('),在确定字面量的值时将忽略它们。

(C++14 起)

解释

使用十进制科学计数法,表示浮点字面量的值是有效数字乘以 10 的 十进制指数 次幂。例如 123e4 的数学含义是 123×104

若浮点字面量以字符序列 0x0X 开始,则该浮点字面量是十六进制浮点字面量。否则,它是十进制浮点字面量

对于十六进制浮点字面量,其有效数字被解释为十六进制有理数,而指数的 数字序列 被解释成有效数字所要乘的 2 的幂的(十进制)整数指数。

double d = 0x1.4p3;// 十六进制分数 1.4(十进制 1.25)的 23,即 10.0

(C++17 起)

注解

虽然十六进制浮点字面量直到 C++17 才成为(标准)C++ 的一部分,但是从 C++11 开始它们已经可以通过输入/输出函数被解析和打印:开启 std::hexfloat 的 C++ 输入/输出流和 C 输入/输出流:std::printfstd::scanf 等。格式描述请参考 std::strtof

功能特性测试宏 标准 功能特性
__cpp_hex_float 201603L (C++17) 十六进制浮点字面量

示例

#include <iomanip>
#include <iostream>
#include <limits>
#include <typeinfo>
 
#define OUT(x) '\n' << std::setw(16) << #x << x
 
int main()
{
    std::cout
        << "字面量" "\t" "打印值" << std::left
        << OUT( 58.            ) // double
        << OUT( 4e2            ) // double
        << OUT( 123.456e-67    ) // double
        << OUT( 123.456e-67f   ) // float, 向零截断
        << OUT( .1E4f          ) // float
        << OUT( 0x10.1p0       ) // double
        << OUT( 0x1p5          ) // double
        << OUT( 0x1e5          ) // 整数字面量,非浮点
        << OUT( 3.14'15'92     ) // double, 忽略单引号 (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 ==  // 结尾为 4
                  3.4028235e38f);   // 结尾为 5
 
    static_assert(3.4028234e38 !=   // 结尾为 4
                  3.4028235e38);    // 结尾为 5
 
    // 以下浮点常量均为 3.4028234e38
    static_assert(3.4028234e38f !=  // float(然后提升为 double)
                  3.4028234e38);    // double
}

可能的输出:

字面量          打印值
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

引用

  • C++23 标准(ISO/IEC 14882:2024):
  • 5.13.4 Floating-point literals [lex.fcon]
  • C++20 标准(ISO/IEC 14882:2020):
  • 5.13.4 Floating-point literals [lex.fcon]
  • C++17 标准(ISO/IEC 14882:2017):
  • 5.13.4 Floating literals [lex.fcon]
  • C++14 标准(ISO/IEC 14882:2014):
  • 2.14.4 Floating literals [lex.fcon]
  • C++11 标准(ISO/IEC 14882:2011):
  • 2.14.4 Floating literals [lex.fcon]
  • C++98 标准(ISO/IEC 14882:1998):
  • 2.13.3 Floating literals [lex.fcon]

参阅

用户定义字面量(C++11) 拥有用户定义后缀的字面量