Namespaces
Variants

Floating constant

From cppreference.net

允许浮点类型的值直接在表达式中使用。

目录

语法

浮点常量是一种 非左值 表达式,其形式为:

有效数字 指数  (可选) 后缀  (可选)

其中 有效数 的格式为

整数部分  (可选) . (可选) 小数部分  (可选)

指数 的形式为

e | E 指数符号  (可选) 数字序列 (1)
p | P 指数符号  (可选) 数字序列 (2) (自 C99 起)
1) 十进制浮点常量的指数语法
2) 十六进制浮点常量的指数语法

可在数字之间插入可选的单引号( ' )作为分隔符,编译时这些符号将被忽略。

(since C23)

说明

有效数字 以字符序列 0x 0X 开头,则该浮点常量为 十六进制浮点常量 。否则为 十进制浮点常量

对于 十六进制浮点常量 有效数字 将被解释为十六进制有理数,而指数的 数字序列 将被解释为有效数字需要缩放到的2的整数次幂。

double d = 0x1.2p3; // hex fraction 1.2 (decimal 1.125) scaled by 2^3, that is 9.0
(since C99)

对于 十进制浮点常量 有效数 被解释为十进制有理数,而指数的 数字序列 被解释为有效数需要缩放的10的整数次幂。

double d = 1.2e3; // 十进制小数1.2乘以10^3,即1200.0

后缀

无后缀的浮点常量具有 double 类型。若 suffix 是字母 f F ,则该浮点常量具有 float 类型。若 suffix 是字母 l L ,则该浮点常量具有 long double 类型。

若实现预定义了宏 __STDC_IEC_60559_BFP__ ,则额外支持以下后缀及对应的浮点常量:

  • 后缀 df DF ,该浮点常量具有类型 _Decimal32
  • 后缀 dd DD ,该浮点常量具有类型 _Decimal64
  • 后缀 dl DL ,该浮点常量具有类型 _Decimal128

十六进制浮点常量中不允许使用十进制浮点类型的后缀。

(C23 起)

可选部分

如果存在指数部分且未使用小数部分,小数点可以省略:

double x = 1e0; // 浮点数 1.0(未使用小数点)

对于十进制浮点常量, 指数部分 是可选的。如果省略指数部分,小数点不可省略,且必须存在 整数部分 小数部分

double x = 1.; // 浮点数 1.0(小数部分可选)
double y = .1; // 浮点数 0.1(整数部分可选)

对于十六进制浮点常量,指数部分不可省略,以避免因 f 后缀被误认为十六进制数字而产生的歧义。

(since C99)

可表示的值

浮点常量的求值结果要么是最接近的可表示值,要么是紧邻最接近可表示值的较大或较小可表示值,具体选择方式由实现定义(换言之,翻译期间的 默认舍入方向 由实现定义)。

所有相同源形式的浮点常量都会转换为具有相同值的相同内部格式。不同源形式的浮点常量,例如 1.23 1.230 ,不一定转换为相同的内部格式和值。

浮点常量可能转换为比其类型所指示的范围和精度更高的表示,具体由 FLT_EVAL_METHOD 指示。例如,常量 0.1f 在表达式中可能表现得如同 0.1L

FLT_RADIX 为2,十六进制浮点常量的求值结果即为该浮点常量所表示的精确值,并正确舍入到目标类型。

(since C99)

具有相同数值 x 但不同量子指数的十进制浮点类型浮点常量,例如 1230 . dd 1230.0dd 1.23e3dd ,具有可区分的内部表示形式。

十进制浮点类型浮点常量的量子指数 q 按以下方式确定: 10 q
在可能的情况下表示 有效数 最后一位数字位置上的1。如果上述确定的量子指数 q 和系数 c=x·10 -q
无法在浮点常量类型中精确表示,则 q 在类型限制范围内按需增大,同时 c 相应减小并进行必要的舍入。该舍入可能导致零或无穷大。若(可能经舍入后的) c q 达到最大值后仍超出允许范围,则生成的浮点常量值为正无穷大。

(C23起)

注释

当浮点常量转换为内部表示时,采用默认的 舍入方向 精度 ,且即使 #pragma STDC FENV_ACCESS 生效(对于字符串的执行时转换,可使用 strtod ),也不会引发 浮点异常 。请注意,这与浮点类型的 算术常量表达式 有所不同。

浮点常量中的字母不区分大小写 ,但十进制浮点类型的后缀不能同时使用大写和小写字母 (C23起) 0x1 . ep + 3 0X1 . EP + 3 表示相同的浮点数值 15.0

setlocale 指定的小数点对浮点常量的语法没有影响:小数点字符始终为句点。

与整数不同,并非所有浮点数值都能直接通过十进制 甚至十六进制 (C99起) 常量语法表示 :宏 NAN INFINITY 以及函数如 nan 提供了生成这些特殊值的方法 (C99起) 。需注意 0x1 . FFFFFEp128f 虽然看似是IEEE浮点数NaN,实际上在该格式中会溢出为无穷大。

不存在负浮点常量;诸如 - 1.2 的表达式是应用于浮点常量 1.2 算术运算符 一元减号。注意特殊值负零可以通过 - 0.0 构造。

示例

#include <stdio.h>
int main(void)
{
    printf("15.0     = %a\n", 15.0);
    printf("0x1.ep+3 = %f\n", 0x1.ep+3);
    // 超出 double 类型范围的常量
    printf("+2.0e+308 --> %g\n",  2.0e+308);
    printf("+1.0e-324 --> %g\n",  1.0e-324);
    printf("-1.0e-324 --> %g\n", -1.0e-324);
    printf("-2.0e+308 --> %g\n", -2.0e+308);
}

输出:

15.0     = 0x1.ep+3
0x1.ep+3 = 15.000000
+2.0e+308 --> inf
+1.0e-324 --> 0
-1.0e-324 --> -0
-2.0e+308 --> -inf

参考文献

  • C23 标准 (ISO/IEC 9899:2024):
  • 6.4.4.2 浮点常量 (p: TBD)
  • C17 标准 (ISO/IEC 9899:2018):
  • 6.4.4.2 浮点常量 (p: 47-48)
  • C11 标准 (ISO/IEC 9899:2011):
  • 6.4.4.2 浮点常量 (p: 65-66)
  • C99标准(ISO/IEC 9899:1999):
  • 6.4.4.2 浮点常量(页码:57-58)
  • C89/C90 标准 (ISO/IEC 9899:1990):
  • 3.1.3.1 浮点常量

参见

C++ 文档 关于 浮点数字面量