unsigned int和double转换顺序

时间:2014-01-15 13:44:58

标签: c++ c type-conversion implicit-conversion

我对unsigned int和double转换顺序感到困惑。我认为在评估表达式时,中间类型是具有代表集的最大基数的类型,但是在代码中

unsigned int a1 = 4294967290, a2 = 4294967100;
unsigned int value1 = (a2 - a1) * double(0.1);
std::cout << value1 << std::endl;
unsigned int value2 = int(a2 - a1)* double(0.1);
std::cout << value2 << std::endl;

使用Microsoft编译器进行编译时,我会收到以下结果:

value1 = 429496710 value2 = 4294967277

虽然我认为答案的直接类型应该是double,因此values1和values2应该相等

我哪里错了?

2 个答案:

答案 0 :(得分:2)

你减去两个unsigned int。对于某些2^k(可能是32),这会运算mod k

在一种情况下,您将其转换为int。如果它大于max int,则结果至少未指定(并且可能是未定义的行为:我忘了)。这可能就是这种情况。在实践中,这将在许多系统上产生负数,但相信这通常是一个坏主意。

然后intunsigned算术转换为double,乘以0.1,然后转换为unsigned int算术模{{1}对于相同的2^k(可能有奇怪的舍入:在转换为无符号之前朝零)。

没有理由认为这些会产生相同的价值。

答案 1 :(得分:2)

  1. 1:在下文中,(a2-a1)的{​​{1}}值为unsigned4294967100 - 4294967290 mod 4294967296。 2:它由4294967106修改,因为在您的平台上,4294967296UINT_MAX
    3:4294967295 - &gt; 4294967106 * 0.1
    4:将(double) 429496710.6分配给(double) 429496710.6会产生value1

    (unsigned) 429496710
  2. 1:如下所示,它更复杂。 unsigned int value1 = (a2 - a1) * double(0.1); 的{​​{1}}值为a2-a1。此值将转换为unsigned,并导致@Yakk建议的未指定/未定义的行为。典型的结果是4294967106int()类型 2:4294967106 - 4294967296 - &gt; -190
    3:将-190 * 0.1分配给(double) -19.0是一个问题,因为它是(double) -19.0的负数,再次遇到UB。
    4:value2被赋予了unsigned的值,这与您平台上的value2位模式相同。

    (unsigned) 4294967277