2011-04-01 23 views
19

我正在做一些數學計算(嘗試使用VS2010將Matlab代碼轉換爲C++),並且我需要能夠判斷某個點是否得到負數0.在C++中檢測一個爲0的負數0

根據IEEE標準-0/+ 0僅在符號位(其餘爲0)上有所不同。

我已經使用了下面的代碼段(post)來解釋我的雙象一個無符號字符

double f = -5; 
    unsigned char *c = reinterpret_cast<unsigned char *>(&f); 
    for(int i=(sizeof(double)-1); i>=0; i--){ 
     printf("%02X", c[i]); 
    } 

5/-5嘗試它,我得到預期的結果:

C014000000000000 (-5) 
4014000000000000 (5) 

但是當我用0/-0進行試驗時,在這兩種情況下我只得到零。 VS2010聲明他們符合IEEE標準(msdn),所以我不確定哪一部分我沒有收到。

如果0/-0確實以完全相同的方式存儲在內存中,如果我需要,我不能將它們分開,所以我應該停止浪費我的時間:)對不對?

+19

嘗試-0.0而不是-0 – wimh 2011-04-01 17:25:15

回答

24

如果你寫

double d = -0; 

將發生以下情況:

首先,-0將被評估,這是int類型的,因爲0是int類型。其結果將是0,然後0將被轉換爲double和分配因而是+0.0,而不是-0.0

double d = -0.0; // is your solution. 
+3

或者你也可以這樣做:double d = -0D;這告訴編譯器直接讀取它作爲一個雙:) – 2011-04-01 17:29:40

+5

@Eamonn:我不相信它是標準的。無論如何,-0.0是「直接讀爲雙」。 – 2011-04-01 17:30:09

+0

我知道我是一個n00b! Thanx :) – vicky5G 2011-04-01 17:32:06

17

除了阿爾緬的很好的答案,你應該使用signbit檢測到這一點。這樣做會保護你的尾數問題:

#include <iostream> 
#include <cmath> 

int main() 
{ 
    std::cout << std::signbit(0.0) << '\n'; 
    std::cout << std::signbit(-0.0) << '\n'; 
} 

0 
1 
0

同種功能改寫成較短的形式:

static inline unsigned bool signbit(double& d) 
{ 
    return (((unsigned char*)&d)[sizeof(double)-1] & 0x80) != 0; 
} 


int EstimateDoubleBufferSize(double& d) 
{ 
    int len = 0; 

    if(signbit(d)) //if (d < 0) 
    { 
     d = -d; 
     len++; 
    } 
    d += 0.0000005; 

    int m = (int) log10(d); 

    if(m < 0) 
     m = 1; // 0.xxxx - include 0 
    else 
     m++; // Include first character 

    len += m + 1 /*dot*/ + 6 /* precision after . */; 
    return len; 
} 

此外,我需要弄清楚微軟C++編譯器的sprintf大小 - 包括該功能以及。