令我惊讶的是,即使可以转换值,int到float转换总是会发出警告。这是为什么?
int i = 0;
float f = 0; // warning here
// I thought this was an implicit conversion,
// meaning it is convertible with no warnings.
f = i; // another warning here
警告是:
warning C4244: '=' : conversion from 'int' to 'float', possible loss of data
答案 0 :(得分:9)
这取决于int
类型中的位数。 IEEE754单精度的浮点数是32位值,但其中一些位被赋值给指数,这意味着并非所有位都可用于精度。
如果您的int
类型的精确度高于float
,那么您可能会在高端失去精确度。
换句话说,它可能无法区分INT_MAX
和INT_MAX - 1
。
在这种情况下,解决方案是使用更宽泛的浮点类型(double
),但从技术上讲,您可能会发现一个具有256位int
类型的实现,在这种情况下,您将拥有找到另一种方式: - )
This answer简要概述了浮点格式的工作原理,包括32位中只有23位可用于尾数的精度。
答案 1 :(得分:3)
我在这里回答了类似的问题:
Why does GCC warn against this implicit conversion?
原因是int
在float
投放到float
时需要进行舍入,因为int
在这种情况下不能包含float
的所有精度。
在您的情况下,int
只有大约24位的精度。虽然{{1}}具有32位精度,但是这种强制转换会导致某些精度损失,因此会出现警告。
答案 2 :(得分:2)
只是为了好玩,尝试一下,看看输出是什么(提示,你会期望数字都是一样的,不是吗?):
int i1(INT_MAX), i2;
float f(i1);
i2 = f;
std::cout << i1 << ' ' << f << ' ' << i2 << '\n';
嗯,我得到的答案是:
2147483647 2.14748e+009 -2147483648
所以编译器非常正确地指出演员可能会出现问题,但是不能确切地知道,因为它只会发生在数值范围的极端。 static_cast&lt;&gt;总是最好的在我看来,至少要清楚,并向编译器显示它是你想要的。
顺便说一句,我不完全确定为什么会出现上述结果。也许别人可以解释一下!
答案 3 :(得分:0)
//我认为这是隐式转换意味着它是可以转换的 没有警告?
不,这不是它的意思。它只是意味着您可以将一种类型的值分配给另一种类型的对象而不进行显式转换(即转换),并且该值将被隐式转换。
在这种情况下,警告可能是适当的。如果int
和float
都是32位(这是典型的但不是通用的),那么int
类型的所有值都在{{1}的范围内但是,有许多float
类型的值无法在int
类型中完全表示。
语言标准要求任何违反语法规则或约束的翻译单元(源文件)至少有一条诊断消息。但编译器可以自由发布任何他们喜欢的附加诊断。