2011-04-01 14 views
19

Estoy haciendo algunos cálculos matemáticos (tratando de convertir el código de Matlab en C++, usando VS2010) y necesito poder decir si en algún momento obtengo un 0 0.Detectando un 0 negativo almacenado como un doble en C++

negativo

De acuerdo con el estándar IEEE -0/+ 0 difieren solo en el bit de signo (el resto son 0).

He utilizado el siguiente fragmento de código (post) para interpretar mi doble como un 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]); 
    } 

Tratando con 5/-5 consigo el resultado esperado:

C014000000000000 (-5) 
4014000000000000 (5) 

Pero cuando lo intento con 0/-0 obtengo solo ceros en ambos casos. VS2010 declara que es compatible con IEEE (msdn), por lo que no estoy seguro de qué parte de él no estoy obteniendo.

Si 0/-0 de hecho están almacenados en la memoria de la misma manera, no hay manera de que pueda distinguirlos si es necesario, así que debería dejar de perder mi tiempo :) ¿Verdad?

+19

pruebe -0.0 en lugar de -0 – wimh

Respuesta

24

Si se escribe

double d = -0; 

sucederá lo siguiente:

En primer lugar, -0 serán evaluados, que es de tipo int, porque 0 es de tipo int. El resultado será 0. A continuación, 0 se convertirá en el doble y le asignó siendo así 0,0, y no -0,0

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

o también puede hacer: double d = -0D; esto le dice al compilador que lo lea directamente como un doble :) –

+5

@Eamonn: No creo que sea estándar. Y -0.0 es "directamente leído como un doble" de todos modos. –

+0

¡Sabía que estaba siendo un n00b! Gracias :) – vicky5G

17

Además de una buena respuesta de Armen, se debe utilizar signbit para detectar esto. Si lo hace, le protegerá de los problemas endian:

#include <iostream> 
#include <cmath> 

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

0 
1 
0

mismo tipo de función reescrito en forma más corta:

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

También necesitaba averiguar C++ tamaño compilador sprintf Microsoft - función para la que se incluye también .

Cuestiones relacionadas