How to convert negative zero to positive zero in C?
How can I fix that in my application?
Code really is not broken, so nothing needs to be "fixed". @kennytm
How can I fix the result so I get a zero when the result should be zero?
To easily get rid of the -
when the result is -0.0
, add 0.0
. Code following standard (IEC 60559 floating-point) rules will produce drop the -
sign.
double nzero = -0.0;
printf("%f\n", nzero);
printf("%f\n", nzero + 0.0);
printf("%f\n", fabs(nzero)); // This has a side effect of changing all negative values
// pedantic code using <math.h>
if (signbit(nzero)) nzero = 0.0; // This has a side effect of changing all negative values
printf("%f\n", nzero);
Usual output.
-0.000000
0.000000
0.000000
0.000000
Yet for general double x
that may have any value, hard to beat the following. @Richard J. Ross III @chqrlie The x + 0.0
approach has an advantage in that likely does not introduce a branch, yet the following is clear.
if (x == 0.0) x = 0.0;
Note: fmax(-0.0, 0.0)
may produce -0.0.
http://en.wikipedia.org/wiki/Signed_zero
The number 0 is usually encoded as +0, but can be represented by either +0 or −0
It shouldn't impact on calculations or UI output.
There is a misunderstanding here about operator precedence:
(double) -2 * 0
is parsed as
((double)(-(2))) * 0
which is essentially the same as (-2.0) * 0.0
.
The C Standard informative Annex J lists as Unspecifier behavior Whether certain operators can generate negative zeros and whether a negative zero becomes a normal zero when stored in an object (6.2.6.2).
Conversely, (double)(-2 * 0)
should generate a positive zero 0.0
on most current platforms as the multiplication is performed using integer arithmetic. The C Standard does have support for architectures that distinguish positive and negative zero integers, but these are vanishingly rare nowadays.
If you want to force zeros to be positive, this simple fix should work:
if (d == 0) {
d = 0;
}
You could make the intent clearer with this:
if (d == -0.0) {
d = +0.0;
}
But the test will succeed also if d
is a positive zero.
Chux has a simpler solution for IEC 60559 complying environments:
d = d + 0.0; // turn -0.0 to +0.0
I did a simple test:
double d = (double) -2.0 * 0;
if (d < 0)
printf("d is less than zero\n");
if (d == 0)
printf("d is equal to zero\n");
if (d > 0)
printf("d is greater than zero\n");
printf("d is: %lf\n", d);
It outputs:
d is equal to zero
d is: -0.000000
So, to fix this, you can add a simple if-check to your application:
if (d == 0) d = 0;