vicky5G
vicky5G

Reputation: 191

Detecting a negative 0 stored as a double in C++

I am doing some mathematical calculations (trying to convert Matlab code into C++, using VS2010) and I need to be able to tell if at some point I get a negative 0.

According to the IEEE standard -0/+0 differ only in the sign bit (the rest are 0).

I have used the following piece of code (post) to interpret my double as a 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]);
   }

Trying it with 5/-5 I get the expected result:

C014000000000000 (-5)
4014000000000000 (5)

But when I try it with 0/-0 I get only zeros in both case. VS2010 states that they are IEEE compliant (msdn) so I'm not sure which part of it I'm not getting.

If 0/-0 are indeed stored in the memory in the exact same way, there is no way I can tell them apart if I need to so I should stop wasting my time :) Right?

Upvotes: 19

Views: 5009

Answers (3)

TarmoPikaro
TarmoPikaro

Reputation: 5243

Same kind of function rewritten into shorter form:

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

Also I needed to figure out microsoft c++ compiler sprintf size - included function for that as well.

Upvotes: 1

Howard Hinnant
Howard Hinnant

Reputation: 219185

In addition to Armen's good answer, you should use signbit to detect this. Doing so will protect you from endian issues:

#include <iostream>
#include <cmath>

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

0
1

Upvotes: 18

Armen Tsirunyan
Armen Tsirunyan

Reputation: 133072

If you write

double d = -0; 

the following will happen:

First, -0 will be evaluated, which is of type int, because 0 is of type int. The result will be 0. Then 0 will be converted to double and assigned thus being +0.0, and not -0.0

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

Upvotes: 25

Related Questions