2014-12-23 69 views
0

有誰知道什麼是C時的參數的一部分,說明了以下行爲:指定排除unsigned int類型爲雙用C

下面的代碼片段重現的情況(注意,有一些樣板代碼,以避免不會導致問題,某些編譯優化):

volatile int zero = 0; 
unsigned int someint = 20; 
if(zero == 1) 
{ 
    someint += 1; 
} 
double x = -someint; 

編譯器(鐺3.5.0,但GCC 4.9.1發出類似)的東西發出的最後分配如下:

mov eax,DWORD PTR [rbp-0xc] <-- move someint in eax 
neg eax 
mov ecx,eax 
cvtsi2sd xmm0,rcx 
movsd QWORD PTR [rbp-0x18],xmm0 

有趣的是,這兩個補碼(NEG)是一個DWORD(EAX),但DWORD雙精度轉換(cvtsi2sd)上的四字進行執行(RCX),其低32位是負數-20(MOV ECX,EAX),其高32位均爲0。 由於EAX沒有符號擴展到RCXRCX現在持有的正數,結束轉換後在x

在另一方面,如果someint澆鑄到在分配的INT,該DWORD到雙精度轉換(cvtsi2sd)是在一個雙字(ECX),因此最終結果進行是預計的-20在x

+0

什麼問題?聽起來對我來說是正確的。 'unsigned int x = -20',轉換爲double,應該是'4294967276.0'。 –

+1

表達式'-someint'將一元'-'運算符應用於'someint'的'unsigned int'值。結果是一個'unsigned int',然後隱式轉換爲'double'。它相當於'unsigned int tmp = -someint;雙x = tmp;' –

回答

4

沒有「負無符號整數」這樣的事情。無符號整數總是正數。如果someint = 0,則-someint產生值0,否則根據C規則產生UINT_MAX + 1 - someint。改用

double x = - (double) someint; 
1

爲了創建一個unsigned int「負」 double您必須首先否定作爲integercastdouble(通過按位否定或改變的跡象):

#include <stdio.h> 

int main() { 

    unsigned int x = 44231;  /* unsigned number    */ 
    int i = ~x;     /* bitwise not gives negative */ 
    double d = (double)i;  /* cast to double    */ 

    double e = (double)(int)~x; /* all in one set of casts  */ 

    printf ("\n unsigned x = %u\n", x); 
    printf (" int i  = ~(x)  = %d\n", i); 
    printf (" double d = (double)i = %lf\n\n", d); 
    printf (" double e = (double)(int)~(x) = %lf\n\n", e); 

    return 0; 
} 

輸出:

$ ./bin/neguint2dbl 

unsigned x = 44231 
int i  = ~(x)  = -44232 
double d = (double)i = -44232.000000 

double e = (double)(int)~(x) = -44232.000000 
0

根據我你需要在將它分配給x之前,將你的someint改爲double型。

相關問題