2015-05-30 40 views
4

我試圖通過附加兩個int的二進制表示來創建double。這是我現在有:通過附加兩個整數的二進制表示形成雙重

int i = arc4random(); 
*(&i+1) = arc4random(); 
double d = *(double*)&i; 

我希望double指針也將在&i+1地址使用的價值,這的確是這樣的。當我打印i*(&i+1)的二進制表示形式並將它們與d的二進制表示形式進行比較時,d由附加*(&i+1)i組成。所以*(&i+1)第一??爲什麼會這樣?

編輯:也看看胡安加泰羅尼亞和馬克西格爾的答案,知道什麼是做我的工會使用的正確方法。

+5

千萬不要這麼做!通過使用未分配給變量的內存來調用未定義的行爲。 –

+0

[C中雙精度的二進制運算](http://stackoverflow.com/q/20458125)。還要記住,用這個方案你可以生成一個'NaN'。 –

+0

如果你真的需要生成一個NaN,'strtod(「NaN」)'。 'strtod(「inf」)'也很有用。 –

回答

1

當我打印i和*(& I + 1)的二進制表示,並將它們與 到d的二進制表示,d通過附加 *(& I + 1)和i組成。所以*(& i + 1)先來?!爲什麼會這樣?

字節的實際排序取決於底層硬件體系結構的'Endian-ness'。

與小端架構:

1) the lowest address byte contains the least significant 8 bits of the total variable 
2) the highest address byte contains the most significant 8 bits of the total variable. 
4

改爲使用union。你仍然可以生成NaN但不會有內存管理問題。

這是union的整體目的,在幾種不同類型之間共享一個內存塊。

確保在你的架構sizeof(double)等於兩倍sizeof(int)

2

您既可以使用一個聯盟,這樣的:

typedef union { 
    double d; 
    struct { 
     int a; 
     int b; 
    } integers; 
} double_generator; 

int main(void) { 
    double_generator g; 
    g.integers.a = arc4random(); 
    g.integers.b = arc4random(); 

    // g.d is now a "randomly generated double" 

    return 0; 
} 

或者「手動」,可能是不安全的,你自己做的工作:

int main(void) { 
    double d; 
    *((int *)&d) = arc4random(); 
    *(((int *)&d) + 1) = arc4random(); 
    printf("%f", d); 
    return 0; 
} 

在這兩種情況下,您只需處理相同的內存,就好像它是intdouble 。這可能會產生每種可能的double值,包括NaNInfinity

但是,此代碼假定sizeof(double)(至少)是sizeof(int)的兩倍。如果不是,你必須引入不同的代碼來處理這個問題。