Reputation: 77
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
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
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