C中的隐式类型转换 [英] Implicit type conversion in C

查看:85
本文介绍了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 is long 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 is double.
  • 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 is float.

这最后一种情况在这里适用: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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆