浮点常量
允许浮点类型的值直接用于表达式中。
目录 |
[编辑] 语法
浮点常量是一个非左值表达式,形式如下:
有效数字 指数 (可选) 后缀 (可选) | |||||||||
其中有效数字的形式如下:
整数部分 (可选) . (可选) 小数部分 (可选) |
|||||||||
指数的形式如下:
e | E 指数符号 (可选) 数字序列 |
(1) | ||||||||
p | P 指数符号 (可选) 数字序列 |
(2) | (C99 起) | |||||||
可选的单引号( |
(自 C23 起) |
[编辑] 解释
如果有效数字以字符序列 对于十六进制浮点常量,有效数字被解释为十六进制有理数,指数的数字序列被解释为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。如果后缀是字母f
或F
,浮点常量类型为float。如果后缀是字母l
或L
,浮点常量类型为long double。
如果实现预定义了宏
十进制浮点类型的后缀不允许用于十六进制浮点常量。 |
(自 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)
对于十六进制浮点常量,指数不是可选的,以避免 |
(C99 起) |
[编辑] 可表示值
浮点常量的求值结果是最近的可表示值,或者是紧邻最近可表示值的更大或更小的可表示值,选择方式由实现定义(换句话说,翻译期间的默认舍入方向由实现定义)。
所有相同源形式的浮点常量都会转换为具有相同值的相同内部格式。不同源形式的浮点常量,例如1.23和1.230,不一定需要转换为相同的内部格式和值。
如果FLT_EVAL_METHOD指示,浮点常量可能转换成比其类型所指示的更大范围和精度。例如,常量0.1f在表达式中可能表现得像0.1L。 如果FLT_RADIX是2,则十六进制浮点常量的求值结果是浮点常量所表示的精确值,并正确舍入到目标类型。 |
(C99 起) |
具有相同数值x但不同量子指数的十进制浮点类型的浮点常量,例如1230.dd、1230.0dd和1.23e3dd,具有可区分的内部表示。 十进制浮点类型浮点常量的量子指数q的确定方式是,如果可能,10q |
(自 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); // 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: 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 浮点常量 (p: 57-58)
- C89/C90 标准 (ISO/IEC 9899:1990)
- 3.1.3.1 浮点常量
[编辑] 参阅
C++ 文档,关于浮点字面量
|