当从int到float和返回时,符号改变 [英] sign changes when going from int to float and back
问题描述
请考虑以下代码,这是我的实际问题的 SSCCE :
Consider the following code, which is an SSCCE of my actual problem:
#include <iostream>
int roundtrip(int x)
{
return int(float(x));
}
int main()
{
int a = 2147483583;
int b = 2147483584;
std::cout << a << " -> " << roundtrip(a) << '\n';
std::cout << b << " -> " << roundtrip(b) << '\n';
}
我的电脑上的输出(Xubuntu 12.04.3 LTS) p>
The output on my computer (Xubuntu 12.04.3 LTS) is:
2147483583 -> 2147483520
2147483584 -> -2147483648
注意正数 b
往返后结束负。这个行为是否明确?我会期望int-to-float round-tripping至少正确保存符号...
Note how the positive number b
ends up negative after the roundtrip. Is this behavior well-specified? I would have expected int-to-float round-tripping to at least preserve the sign correctly...
Hm,在ideone 上,输出是不同的:
Hm, on ideone, the output is different:
2147483583 -> 2147483520
2147483584 -> 2147483647
g ++团队在此期间修复了错误还是两个输出完全有效? p>
Did the g++ team fix a bug in the meantime, or are both outputs perfectly valid?
推荐答案
您的程序正在调用未定义的行为,因为在从浮点到整数的转换中出现溢出。您看到的只是x86处理器上的常见症状。
Your program is invoking undefined behavior because of an overflow in the conversion from floating-point to integer. What you see is only the usual symptom on x86 processors.
float
> 2147483584
The float
value nearest to 2147483584
is 231 exactly (the conversion from integer to floating-point usually rounds to the nearest, which can be up, and is up in this case. To be specific, the behavior when converting from integer to floating-point is implementation-defined, most implementations define rounding as being "according to the FPU rounding mode", and the FPU's default rounding mode is to round to the nearest).
然后,当从代表2 31 的float的转换到 int
时,会发生溢出。这个溢出是未定义的行为。一些处理器引发异常,其他处理器饱和。通常由编译器生成的IA-32指令 cvttsd2si 在溢出的情况下总是返回
INT_MIN
Then, while converting from the float representing 231 to int
, an overflow occurs. This overflow is undefined behavior. Some processors raise an exception, others saturate. The IA-32 instruction cvttsd2si
typically generated by compilers happens to always return INT_MIN
in case of overflow, regardless of whether the float is positive or negative.
您不应该依赖这种行为,即使您知道您的目标是Intel处理器:当定位x86-64时,编译器可以发射从浮点到整数的转换,指令序列未定义行为的优点是返回结果,而不是您可能期望的目标整数类型。
You should not rely on this behavior even if you know you are targeting an Intel processor: when targeting x86-64, compilers can emit, for the conversion from floating-point to integer, sequences of instructions that take advantage of the undefined behavior to return results other than what you might otherwise expect for the destination integer type.
这篇关于当从int到float和返回时,符号改变的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!