命名空间
变体
操作

浮点常量

来自 cppreference.com
< c‎ | 语言

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

内容

[编辑] 语法

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

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

其中 有效数字 的形式为

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

指数 的形式为

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

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

(自 C23 起)

[编辑] 解释

如果 有效数字 以字符序列 0x0X 开头,则浮点常量为 *十六进制浮点常量*。否则,它为 *十进制浮点常量*。

对于 *十六进制浮点常量*,有效数字 被解释为十六进制有理数,数字序列 被解释为有效数字需要乘以的 2 的整数次幂。

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

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

double d = 1.2e3; // decimal fraction 1.2 scaled by 10^3, that is 1200.0

[编辑] 后缀

无后缀浮点常量的类型为 double。如果 后缀 为字母 fF,则浮点常量的类型为 float。如果 后缀 为字母 lL,则浮点常量的类型为 long double

如果实现预定义了宏 __STDC_IEC_60559_BFP__,则还支持以下后缀和相应的浮点常量

  • 如果 后缀dfDF,则浮点常量的类型为 _Decimal32;
  • 如果 后缀ddDD,则浮点常量的类型为 _Decimal64;
  • 如果 后缀dlDL,则浮点常量的类型为 _Decimal128

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

(自 C23 起)

[编辑] 可选部分

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

double x = 1e0; // floating-point 1.0 (period not used)

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

double x = 1.; // floating-point 1.0 (fractional part optional)
double y = .1; // floating-point 0.1 (whole-number part optional)

对于十六进制浮点常量,指数部分不是可选的,以避免由于 f 后缀被误认为十六进制数字而导致的歧义。

(自 C99 起)

[编辑] 可表示值

求值浮点常量的结果是:最接近的可表示值,或者与最接近的可表示值相邻的较大或较小的可表示值,以实现定义的方式选择(换句话说,默认舍入方向 在编译期间是实现定义的)。

所有具有相同源代码形式的浮点常量都转换为具有相同值的相同内部格式。具有不同源代码形式的浮点常量(例如 1.231.230)不一定转换为相同的内部格式和值。

浮点常量可以转换为比其类型指示的更大范围和精度,如果由 FLT_EVAL_METHOD 指示。例如,常量 0.1f 可以在表达式中像 0.1L 一样起作用。

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

(自 C99 起)

具有相同数值 x 但量子指数不同的十进制浮点类型浮点常量(例如 1230.dd1230.0dd1.23e3dd)具有可区分的内部表示。

十进制浮点类型浮点常量的量子指数 q10q
有效数字 的最后一位数字处表示 1 的方式确定(如果可能)。如果上面确定的量子指数 q 和系数 c=x·10-q
在浮点常量类型中不能精确地表示,则在类型的范围内根据需要增加 q,并相应地减少 c,同时进行必要的舍入。舍入可能会导致零或无穷大。如果(可能已舍入的)cq 达到最大值后仍然超出允许范围,则生成的浮点常量的值为正无穷大。

(自 C23 起)

[编辑] 注释

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

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

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

与整数不同,并非所有浮点值都可以直接用十进制甚至十六进制(自 C99 起)常量语法表示: 宏 NANINFINITY 以及诸如 nan 之类的函数提供了生成这些特殊值的方法(自 C99 起)。请注意,0x1.FFFFFEp128f,它看起来像是 IEEE float 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);
 
    // Constants outside the range of type 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: 待定)
  • 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 浮点常量 (p: 57-58)
  • C89/C90 标准 (ISO/IEC 9899:1990)
  • 3.1.3.1 浮点常量

[编辑] 另请参阅

C++ 文档 用于 浮点文字