具有指数部分的浮点文字的类型是什么,例如123456e-3在 C(99+) 中?它是类型float还是double?当用作float初始化器时float f = 123456e-3;
,它需要有f后缀吗?
默认情况下,所有带或不带指数部分的浮点文字都具有 type double。您可以添加f后缀来制作类型float或L制作类型long double。
在的情况下float f = 123456e-3;,你初始化float一个double常量,所以精度损失的可能性,但是这种特殊的常量只有具有精度是6位小数所以应该没问题。
对于浮点字面量,如果没有定义后缀,它会自动被认为是double.
您可以按照此图表获取后缀:
(no suffix) - double
f/F - float
l/L - long double
Run Code Online (Sandbox Code Playgroud)
所以,对于浮动,它需要有f后缀。
浮点文字的类型是什么?
浮动常量
C 将这些定义为浮动常量,而不是文字。默认类型为double.
一个f或F后缀使得它float。
一个l或L后缀使得它long double。
[编辑] FLT_EVAL_METHOD
C具有FLT_EVAL_METHOD其允许常量被解释为更广泛的类型。
例子 FLT_EVAL_METHOD == 2
根据
long double类型的范围和精度评估所有操作和常量。
在这种情况下,我希望v1和v2具有相同的值 when FLT_EVAL_METHOD == 2,但不同的值 when FLT_EVAL_METHOD == 0。
long double v1 = 0.1;
long double v2 = 0.1L;
Run Code Online (Sandbox Code Playgroud)
当用作 float f = 123456e-3 中的 float 初始值设定项时;它需要有后缀吗?
为了最好地将文本转换为float,是的,请使用f.
float f = 123456e-3导致双舍入。2 舍入发生: text->double和doubleto float。
使用 select 值,g可能会使用float g = x.xxxvs获得不同的值g = x.xxxf;。见下文。
双舍入示例
请注意f2,f4除了f后缀外,和具有相同的常量。编译器警告f4:
警告:从 'double' 到 'float' 的转换会将值从 '9.9999997019767761e-1' 更改为 '1.0e+0f' [-Wfloat-conversion]
#include <stdlib.h>
int main(void) {
// float has 24 bit significand, double has 53
float f1 = 0x0.FFFFFFp0f; // code with 24 bit significand, exact as a float
printf("%-20a %.17e\n", f1, f1);
float f2 = 0x0.FFFFFF7FFFFFFCp0f; // code with 54 bit significand, rounds down to nearest float
printf("%-20a %.17e\n", f2, f2);
float f3 = 0x0.FFFFFF80000000p0f; // code with 25 bit significand, rounds up to nearest float
printf("%-20a %.17e\n", f3, f3);
puts("");
double d1 = 0x0.FFFFFF7FFFFFF8p0; // code constant with 53 bit significand, exact as a double
printf("%-20a %.17e\n", d1, d1);
double d2 = 0x0.FFFFFF7FFFFFFCp0; // code constant with 54 bit significand, rounds up to nearest double
printf("%-20a %.17e\n", d2, d2);
float f4 = 0x0.FFFFFF7FFFFFFCp0; // code constant with 54 bit significand, rounds up to nearest double
// then rounds up again when double converted to float
printf("%-20a %.17e\n", f4, f4);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出
0x1.fffffep-1 9.99999940395355225e-01
0x1.fffffep-1 9.99999940395355225e-01 f2
0x1p+0 1.00000000000000000e+00
0x1.fffffefffffffp-1 9.99999970197677501e-01
0x1.ffffffp-1 9.99999970197677612e-01
0x1p+0 1.00000000000000000e+00 f4 Double Rounding!
Run Code Online (Sandbox Code Playgroud)
为了最好地将文本转换为long double,一定要使用Lelse 常量只是double精度较低的a 。
long double ld1 = 0x1.00000000000001p1;
printf("%.20Le\n", ld1, ld1);
long double ld2 = 0x1.00000000000001p1L; // "Same" constant as above with an 'L'
printf("%.20Le\n", ld2, ld2);
Run Code Online (Sandbox Code Playgroud)
输出
2.00000000000000000000e+00
2.00000000000000002776e+00
Run Code Online (Sandbox Code Playgroud)