我使用的编译器是g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4.
signed,unsigned和float类型之间的转换如何工作?
我编译我的程序使用以下命令:
g++ -std=c++11 -pedantic -Wall program.cpp
程序没有。 1:
#include <iostream>
using namespace std;
int main() {
unsigned int b;
b = -54;
cout << b << endl;
return 0;
}
该程序打印4294967242,这是我的预期值,因为这样的话,当我们指定外的范围内的值,以无符号类型的变量,所以结果是模数的其余部分。
该程序没有。 2:
#include <iostream>
using namespace std;
int main() {
unsigned int b;
b = 54.1234;
cout << b << endl;
return 0;
}
该程序打印54,并且这也行,因为所存储的值是小数点之前的部分,和所述franctional部分被截断。
该程序没有。 3:
#include <iostream>
using namespace std;
int main() {
unsigned int b;
b = -54.1234;
cout << b << endl;
return 0;
}
编译期间
在这里,我得到警告“溢出隐不断转换”。
程序打印0.为什么这样?我认为它会完成小数部分的截断(如程序2),然后存储模数除法的结果(如程序1)。
但是,如果我写程序没有。 4 .:
程序号码。 4.
#include <iostream>
using namespace std;
int main() {
unsigned int b;
float k = -54.1234;
b = k;
cout << b << endl;
return 0;
}
然后我没有得到任何警告,我得到的结果(由我预期)4294967242,这是模除法的结果。
如果有人能解释给我,我将不胜感激。
为什么程序没有。 3的行为与程序编号不同。 4?编译程序编号时,为什么不发出警告? 1,但编译程序时我得到一个。 3.?
程序3是唯一一个具有恒定转换和整数溢出的程序。显然这就是编译器的工作原理。我可以仔细阅读语言规范的文本,试着找出可能发生的原因,但看起来你比我有更多的时间。如果我猜测,这可能是未定义的行为,这就是为什么你不首先编写程序3的原因。 –
一般来说,依靠一致的溢出行为来正确执行程序操作可能不是一个好主意,除非你的问题域特别需要这样的一点点操作。 –
由于x86指令集中有一个怪癖,当从浮点到整数的转换发生溢出时,观察到的行为可能非常令人惊讶。请参阅http://blog.frama-c.com/index.php?post/2013/10/09/Overflow-float-integer –