当从int到float和返回时,符号改变 [英] sign changes when going from int to float and back

查看:276
本文介绍了当从int到float和返回时,符号改变的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码,这是我的实际问题的 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屋!

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