2011-04-01 12 views
19

Bazı matematiksel hesaplamalar yapıyorum (Matlab kodunu VS2010 kullanarak C++' ya dönüştürmeye çalışıyorum) ve bir noktada negatif 0 aldığımı anlayabilmem gerekiyor.C++ 'da çift olarak saklanan bir negatif 0'ı algılamak

IEEE standardına göre -0/+ 0 yalnızca işaret biti (kalanlar 0'dır).

ben 5/-5 ile çalışılıyor bir unsigned char

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

olarak benim çift yorumlamak için kod (post) aşağıdaki parça kullandık Beklediğim sonuç almak:

C014000000000000 (-5) 
4014000000000000 (5) 

Ama ben 0/-0 ile denediğimde her iki durumda da sadece sıfırları alırım. VS2010, IEEE uyumlu olduklarını belirtir (msdn).

Eğer 0/-0 gerçekten bellekte aynı şekilde saklanıyorsa, onlara ihtiyacım olursa bunları ayırt etmenin bir yolu yoktur, bu yüzden zamanımı boşa harcamam gerekir :) Doğru mu?

+19

-0 – wimh

cevap

24

Eğer

double d = -0; 

yazarsanız şunlar olacaktır: 0 int türünde çünkü

Birincisi, -0, int türünde olan değerlendirilecektir. Sonuç 0. Sonra 0 Armen en iyi cevap ilaveten

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

yerine -0.0 deneyin veya şunları yapabilirsiniz: çift d = -0D; Bu derleyiciyi doğrudan bir çift olarak okumasını söyler :) –

+5

@Eamonn: Standart olduğuna inanmıyorum. Ve -0.0 zaten "doğrudan çift olarak okunur". –

+0

N00b olduğumu biliyordum! Thanx :) – vicky5G

17

-0.0 katına dönüştürülür ve böylece +0.0 olmanın atanır ve edilmeyecektir olacak, bu algılamak için signbit kullanmalıdır. Aksi takdirde endian konulara karşı koruyacaktır: kısa forma yeniden yazılmış fonksiyonun

#include <iostream> 
#include <cmath> 

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

0 
1 
0

Aynı tür:

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; 
} 

Ayrıca ben microsoft C++ derleyicisi sprintf boyunu anlamak için gerekli - bunun için de işlevini dahil .