TranslateProject/published/201505/20150124 Why does C++ promote an int to a float when a float cannot represent all int values.md

43 lines
3.7 KiB
Markdown
Raw Permalink Normal View History

2015-03-08 11:10:54 +08:00
既然float不能表示所有的int那为什么在类型转换时C++将int转换成float
=============
2015-03-08 11:10:54 +08:00
###问题:
2015-03-08 11:10:54 +08:00
代码如下:
```C
int i = 23;
float f = 3.14;
if (i == f) // 执行某段代码
```
编译器会将i转换成float类型然后比较这两个float的大小但是float能够表示所有的int吗为什么没有将int和float转换成double类型进行比较呢
###回答:
2015-03-08 11:10:54 +08:00
在整型数的演变中,当`int`变成`unsigned`时,会丢掉负数部分(有趣的是,这样的话,`0u < -1`就是对的了
和C语言中的大部分机制在C++中得到继承一样就硬件操作而言常见的算术转换应该简明易懂。C语言的发明者精通他们所使用机器上的汇编语言他们编写的C语言对他们和像他们一样编写程序的人有直接的意义直到使用汇编语言编写诸如UNIX内核的程序时。
现如今一般来说处理器并不具有混合类型的指令系统如float和double相加、比较int和float诸如此类因为如果这样做造成芯片晶圆的巨大浪费——如果你想支持更多不同的类型你不得不实现更多的操作码。然而在实际中你只有实现"add int to int"、"compare float to float"和"multiply unsigned with unsigned"等功能的常见指令,这使得优先进行算术转换变得很有必要——它们是指令系统中两种类型的映射关系,它们中的大部分很有用处。
从习惯编写低级别机器代码的编程人员的角度来说如果有了混合类型那么在一般情况下最有可能使用的汇编指令就是那些只需要进行最少类型转换的指令。其中有一种特殊情况就是浮点数的转换特别是在20世纪70年代早期当时C语言正在被开发计算机运行速度很慢而浮点数的计算是通过软件完成的所以进行转换的成本很高。这拖慢了常用算术运算的转换开发——当时只有一种操作数实现了转换这个例外就是long到unsigned int的转换这种转换没有任何要求在大部分机器上都可以进行。当然并不是全部因为总有例外情况
所以,编写常用的算术转换是为了完成汇编程序员在大部分时间需要做的事情:即有两种不匹配的类型,将一种转换成另一种。这也就是汇编代码所做的事情,除非有特别原因需要进行其它类型转换。对于那些习惯编写汇编代码的人来说,除非是特殊需要,才会被迫去编写一种不同的类型转换。显然,这种情况下提出编写转换是很自然的事情。虽然,你可以简单地写成这样
```C
if((double) i < (double) f)
```
顺便提一下,在这个问题中有趣的是,`unsigned`的优先级高于`int`,所以把`int`和`unsigned`进行比较时最终进行的是unsigned类型的比较开头提到的`0u < -1`就是这个道理我猜测这可能是在早些时候计算机发展初期当时的人们认为`unsigned``int`在所表示的数值范围上受到的限制更小现在还不需要符号位所以可以使用额外的位来表示更大的数值范围如果你觉得`int`可能会溢出那么就使用unsigned好了在使用16位表示的ints时这个担心会更明显
----
via: [stackoverflow](http://stackoverflow.com/questions/28010565/why-does-c-promote-an-int-to-a-float-when-a-float-cannot-represent-all-int-val/28011249#28011249)
2015-03-08 11:10:54 +08:00
作者:[wintermute][a]
译者:[KayGuoWhu](https://github.com/KayGuoWhu)
校对:[wxy](https://github.com/wxy)
2015-03-08 11:10:54 +08:00
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创翻译,[Linux中国](http://linux.cn/) 荣誉推出
[a]:http://stackoverflow.com/users/4301306/wintermute