spozzi
spozzi

Reputation: 77

How can I differentiate between zero and negative zero?

I'm implementing the printf() function. Nearly everything works correctly, but I have an issue when called as ft_printf("%f", -0.0). My program outputs 0.0 instead of -0.0. I can't use any libraries.

My condition for checking for negativity is simply "x<0" which doesn't include my problem. I've found a promising solution in Distinguish zero and negative zero.

this is what seems would solve my problem:

double a = -0.0;
printf("%d\n", (*((long *)&a) == 0x8000000000000000));

I'd like for this program to print 1 but in my program when I do it in my code it outputs 0. The part I have a problem understanding is how this: *((long *)&a) makes a number comparable to its hexadecimal counterpart.

Upvotes: 1

Views: 904

Answers (2)

S.S. Anne
S.S. Anne

Reputation: 15566

This is similar to a Codewars Kata that I completed. The trick is to divide by the number that you want to check is negative zero, like this:

int isPositiveZero(double a) {
    return 1/a == 1/0.0;
}

The division gives -infinity if a is negative zero, and infinity if a is zero.

If you want to do it your way, try this:

(*((long *)&a) & 0x8000000000000000)

Note that this violates the strict aliasing rule, which causes undefined behavior. This means that your program could do anything from printing the right result to making your computer sprout wings and fly away.

If you have math.h available and don't have an aversion to using macros from the standard C library, then this solution (using signbit) will also work (and be much more portable):

#include <math.h>

int isPositiveZero(double a) {
    return a == 0.0 && !signbit(a);
}

Upvotes: 3

John Bollinger
John Bollinger

Reputation: 180103

The C math library (part of the standard library) provides a signbit macro that is absolutely the simplest and most portable way to check the sign of a floating-point number. If your requirement to avoid libraries means third-party libraries then it will serve your purpose.

Example:

#include <math.h>
#include <stdio.h>

void putsign(double d) {
    if (signbit(d)) {
        putchar('-');
    } else {
        putchar('+');
    }
}

Upvotes: 7

Related Questions