tags:

views:

557

answers:

3

I was just using gdb to print out a value of a double and to my surprise it printed -0

What is a double of -0 value mean in C?

By the way when I checked it's equality with 0 it returned true: To do the comparison I just did the following

in gdb

> print some_double
-0
> print some_double == 0
1
+13  A: 

I know some hate just linking to Wikipedia, but you should read up on the concept of Negative Zero in computing and floating point numbers.

Randolpho
+5  A: 

This is a well known issue with printf. Since you are using a floating point number, there is no one representation possible in binary. And most of the times the binary representation is not perfect. So, 0 is stored as 0.00000000000000...0042 sometimes and as -0.000000000000000000000123. When printf prints the second one, you get the odd -0.

I don't really know how you are comparing against 0, just remember to add an epsilon when doing floating point comparisons to adjust for oddities. E.g: to test if two floats are equal never write a == b but fabs(a-b) < 1e-13 where 1e-13 is the epsilon (choose an exponent that suits you).

dirkgently
I added how I did the comparison
hhafez
do you think that gdb is printf for it's print statements?
hhafez
yep, all those programs use the same libc.
dirkgently
Many numbers have IEEE 754 floating point representations that are "perfect". Including 0. And -0.
bk1e
@bk1e: updated so that 'you' can understand better.
dirkgently
Why should -0.000000000000000000000123 be printed as -0? As bk1e said, 0 and -0 are perfectly representable in floating point. No need for any rounding.
Joachim Sauer
@saua: That is not rounding. It is called tolerance.
dirkgently
I'm not arguing against fuzzy comparisons. Saying that 0 is represented as a value that is not 0 is misleading, because 0 can be represented precisely. If the original poster's variable "some_double" contained -1.23e-22, "print some_double == 0" would have printed "0", not "1". -1.23e-22 is not 0.
bk1e
@bk1e: That's the ideal case -- initialization is a good candidate. However, most of the time, values are generated after expression evaluation -- this is when these issues creep in.
dirkgently
A: 

Actually reading the book "Writing great code, Volume 1" in Chapter 4 the author gives the answer quite clearly it is because of the use of 1's complement to represent signed float in IEEE FP Standard. He says:

The mantissa uses a one’s complement format rather than two’s complement. This means that the 24-bit value of the mantissa is simply an unsigned binary number, and the sign bit, in bit position 31, determines whether that value is positive or negative. One’s complement numbers have the unusual property that there are two representations for zero (with the sign bit set or clear). Generally, this is important only to the person designing the floating-point software or hardware system.

Emphasis mine

hhafez