在C中,在没有警告的情况下为浮点变量指定双常量?

在C中,在没有警告的情况下为浮点变量指定双常量?,c,floating-point,C,Floating Point,在C编程语言中,浮点常量默认为双精度类型 所以3.1415是双精度类型,除非使用“f”或“f”后缀表示浮点类型 我假设const float pi=3.1415会引起警告,但实际上不会 当我在gcc with-Wall下尝试这些时: float f = 3.1415926; double d = 3.1415926; printf("f: %f\n", f); printf("d: %f\n", d); f = 3.1415926f; printf("f: %f\n", f)

在C编程语言中,浮点常量默认为双精度类型
所以
3.1415
是双精度类型,除非使用“f”或“f”后缀表示浮点类型

我假设
const float pi=3.1415
会引起警告,但实际上不会

当我在gcc with-Wall下尝试这些时:

float f = 3.1415926;  
double d = 3.1415926;  
printf("f: %f\n", f);  
printf("d: %f\n", d);  
f = 3.1415926f;  
printf("f: %f\n", f);  
int i = 3.1415926;  
printf("i: %d\n", i);  
结果是:

f: 3.141593  
d: 3.141593  
f: 3.141593  
i: 3
结果(包括双变量)显然失去了精度,但编译时没有任何警告。

那么编译器对这个做了什么呢?还是我误解了什么?

%f
可以与
float
double
一起使用。如果你想要更精确的使用

printf("f: %.16f",d);
这就是引擎盖下发生的事情:

float f = 3.1415926;  // The double 3.1415926 is truncated to float
double d = 3.1415926;  
printf("f: %f\n", f);  
printf("d: %f\n", d);  
f = 3.1415926f;       // Float is specified
printf("f: %f\n", f);  
int i = 3.1415926;    // Truncation from double to int
printf("i: %d\n", i); 

-Wall
不启用有关精度损失、值截断等的警告。因为这些警告是恼人的噪音,“修复”它们需要用大量难看的类型转换将正确的代码弄乱。如果需要这种性质的警告,则需要显式启用它们


另外,您使用的
printf
与实际变量的精度无关,只是打印时的精度
printf
,默认为小数点后6位。

如果您想得到警告,我相信
-Wconversion
会在主线gcc-4.3及更高版本中标记它们


如果您碰巧使用OS X,
-Wshorten-64-to-32
自GCC-4.0.1以来一直在苹果的GCC中标记它们。但是,我相信,clang与主线gcc行为相匹配。

对于double,这不应该是
%lf
吗?@sharth:
lf
f
对于
scanf
是不同的,但是在
printf
中相同
printf
的变量性质确保浮点在通过时隐式转换为double?是的,虽然这与OP的问题无关,但我想知道哪一个更大:“从双精度到浮点”消息捕获的错误数,或者当程序员必须显式地强制许多事情进行浮点运算以使编译器满意时,代码所导致的错误数,还迫使
float
一些本不应该是的东西[例如
const float oneTenth=1.0f/10.0f;float value1=8.0f*oneTenth;double value2=4.0f*oneTenth;
注意,如果
oneTenth
可以是
double
,那么一切都会完美工作。