2014-01-15 67 views
2

我對無符號整型和雙轉換順序感到困惑。我認爲,在計算表達式時,中間類型是一個與代表組的最大基數,但這裏的代碼無符號整型和雙轉換順序

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; 

當微軟編譯器編譯,我得到這些結果:

值1 = 429496710 值2 = 4294967277

而我認爲即時型的回答應該是雙,因此值1和values2應該是平等的

在哪裏 我錯了嗎?

回答

2
  1. 1:在下文中,(a2-a1)具有4294967100 - 4294967290 mod 42949672964294967106unsigned值。
    2:它由4294967296修改,因爲在您的平臺上,UINT_MAX4294967295
    3:4294967106 * 0.1 - >(double) 429496710.6
    4:在一個(unsigned) 429496710分配(double) 429496710.6value1結果。

    unsigned int value1 = (a2 - a1) * double(0.1); 
    
  2. 1:隨着下面,它是更復雜。 a2-a1unsigned值爲4294967106。此值將轉換爲int(),並導致@Yakk建議的未指定/未定義的行爲。典型的結果是4294967106 - 4294967296-190
    2:-190 * 0.1 - >(double) -19.0
    3:分配給(double) -19.0value2是一個問題,因爲它是用於unsigned負數,再次遇到UB。
    4:value2被指定爲(unsigned) 4294967277的值,它與您的平臺上的(int) -19的位模式相同。

    unsigned int value2 = int(a2 - a1)* double(0.1); 
    
2

你減去兩個unsigned int。對於某些k(可能是32),這可以算術模塊2^k

在一種情況下,您將其轉換爲int。如果它大於max int,則結果至少未指定(可能是未定義的行爲:我忘記了)。這可能就是這種情況。實際上,這會在許多系統上產生一個負數,但相信這通常是一個壞主意。

然後intunsigned轉換爲double算術乘以0.1,並且然後轉換成一個unsigned int arithmatically MOD 2^k對於相同k(具有可能奇怪舍入回事:轉換爲無符號之前向零) 。

沒有理由認爲這些會產生相同的價值。