does -0 exist?

Started by
17 comments, last by Vorpy 17 years ago
I have a quick question about floating point numbers. I'm using VC++ Express. I have the following code.
double j = 0.0;
j *= -1.0;
cout << j << endl;
It outputs -0. I didn't think -0 exists. I know that floating point numbers have a sign bit, so when it multiplies it by -1 does it just flip that bit and make it look negative? Is there a way to fix this? I don't see any real problems with it, but it looks weird. Thanks.
Advertisement
In IEEE standard 754 floating point there is definitely a -0. I believe in most cases it will behave exactly like 0. It might differ in the case of a division by zero, I'm not really sure (the representation would then become a special value that represents infinity or possibly negative infinity, I believe).

If you want to avoid printing a -0 for display purposes, just write some code to test for it and flip it around if it happens.
Quote:Original post by Vorpy
If you want to avoid printing a -0 for display purposes, just write some code to test for it and flip it around if it happens.


Of course that is pretty complicated since +0 == -0 in C++ even though their representation isn't equal. The simplest way to test for negative zero I know of is to divide a positive integer with the zero and check whether the result is positive or negative infinity.

The way I would do it would be to test for zero (positive or negative) and just square the zero, then you are guaranteed to get positive zero.
Well the simplest way i could think of would be to add a positive value and then promptly subtract it, this would leave you with +0.0

However it appears that simply adding +0.0 also does the job, so no subtraction necessary.

The following works for me:

double j = 0.0;j *= -1.0;j += 0.0;cout << j << endl;
Quote:Original post by dmatter
However it appears that simply adding +0.0 also does the job, so no subtraction necessary.


That's interesting, is this behavoir defined in the standard ?
And is -0 + +0 the same as +0 - +0 or +0 + -0 ?
Or, you could actually check if the sign bit is set on the number:
float number;bool negative = (*((int *)&number) & (1 << 31) > 0);
Or have a look into the wiki:
http://en.wikipedia.org/wiki/%E2%88%920_%28number%29
Quote:Original post by nmi
Or have a look into the wiki:
http://en.wikipedia.org/wiki/%E2%88%920_%28number%29

Good to see my solution features on that page [smile]
This is due to the codage of the double number.
64 bits :
1 bit for the sign (s) (siwtch to 0 and -0)
11 bits for exposant (e)
52 bits for mantisse (m)

the double is computed as (-1)^s * m*10^e

Note that, for an integer number, there is no -0.
The codage of an unsigned integer is (for a char) 0..255

For a signed number, the codage is -128..127
There is a super tip of codage :

the order of codage is 0,1,2,3,....,127,-128,-127,-126,...,-1
(-1 is always 0xFF (short), 0xFFFF (char), 0xFFFFFFFF (int))

why ?
To have easyly (for a number n), -n (and to substract)
Getting the opposite of n is just switching all bits, then adding 1.

example :

opposite of 1 : coded 00000001
switch all bits : 11111110
then add 1 : 11111111 -> 0xFF

other example :

opposite of 0 : coded 00000000
switch all bits : 11111111
then add 1 : 00000000 (stay in basis 8 bits, flag Carry), then it is still 0.

I love codage.
Quote:Original post by DaBono
Or, you could actually check if the sign bit is set on the number:
float number;bool negative = (*((int *)&number) & (1 << 31) > 0);


As well as being non-portable because it relies on the underlying representation of floating point numbers, that code breaks the strict aliasing rules and thus will result in undefined behaviour.

This topic is closed to new replies.

Advertisement