C中的隐式类型转换 [英] Implicit type conversion in C
问题描述
我偶然发现了维基百科上的以下示例( http://en.wikipedia.org/wiki /Type_conversion#Implicit_type_conversion ).
I stumbled upon the following example on wikipedia (http://en.wikipedia.org/wiki/Type_conversion#Implicit_type_conversion).
#include <stdio.h>
int main()
{
int i_value = 16777217;
float f_value = 16777217.0;
printf("The integer is: %i\n", i_value); // 16777217
printf("The float is: %f\n", f_value); // 16777216.000000
printf("Their equality: %i\n", i_value == f_value); // result is 0
}
他们的解释:这种奇怪的行为是由于i_value的隐式强制转换与f_value进行比较时会浮动;这种强制转换会失去精度,从而使所比较的值有所不同."
Their explanation: "This odd behavior is caused by an implicit cast of i_value to float when it is compared with f_value; a cast which loses precision, making the values being compared different."
这不是错吗?如果将i_value强制转换为float,则两者的精度损失相同,并且相等. 因此,必须将i_value强制转换为两倍.
Isn't this wrong? If i_value were cast to float, then both would have the same loss in precision and they would be equal. So i_value must be cast to double.
推荐答案
不,对于等号运算符,发生通常的算术转换" ,该操作开始于:
No, in the case of the equality operator, the "usual arithmetic conversions" occur, which start off:
- 首先,如果一个操作数的对应实型为
long double
,则另一个操作数将被转换,而不会改变类型 域,将其转换为对应的实型为long double
的类型.- 否则,如果任一操作数的对应实型为
double
,则将转换另一个操作数,而不会更改类型 域,将其转换为对应的实型为double
的类型.- 否则,如果任一操作数的对应实型为
float
,则将转换另一个操作数,而不会更改类型 域,将其转换为对应的实型为float
的类型.
- First, if the corresponding real type of either operand is
long double
, the other operand is converted, without change of type domain, to a type whose corresponding real type islong double
.- Otherwise, if the corresponding real type of either operand is
double
, the other operand is converted, without change of type domain, to a type whose corresponding real type isdouble
.- Otherwise, if the corresponding real type of either operand is
float
, the other operand is converted, without change of type domain, to a type whose corresponding real type isfloat
.
这最后一种情况在这里适用:i_value
转换为float
.
This last case applies here: i_value
is converted to float
.
您可以从比较中看到奇怪结果的原因,尽管这是对常规算术转换的警告:
The reason that you can see an odd result from the comparison, despite this, is because of this caveat to the usual arithmetic conversions:
浮点操作数的值和浮点结果的值 表达式可以比更高的精度和范围来表示 类型所要求的;类型不会因此改变.
The values of floating operands and of the results of floating expressions may be represented in greater precision and range than that required by the type; the types are not changed thereby.
这是正在发生的事情:转换后的i_value
的类型仍然是float
,但是在此表达式中,您的编译器正在利用这种纬度并以比float
更高的精度来表示它.在编译与387兼容的浮点时,这是典型的编译器行为,因为编译器将临时值留在浮点堆栈上,该堆栈以80位扩展精度格式存储浮点数.
This is what is happening: the type of the converted i_value
is still float
, but in this expression your compiler is taking advantage of this latitude and representing it in greater precision than float
. This is typical compiler behaviour when compiling for 387-compatible floating point, because the compiler leaves temporary values on the floating point stack, which stores floating point numbers in an 80bit extended precision format.
如果编译器为gcc
,则可以通过提供-ffloat-store
命令行选项来禁用此附加精度.
If your compiler is gcc
, you can disable this additional precision by giving the -ffloat-store
command-line option.
这篇关于C中的隐式类型转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!