我正在实现printf()
函数。几乎所有东西都可以正常工作,但是当被称为ft_printf("%f", -0.0)
时我遇到了问题。我的程序输出0.0
而不是-0.0
。我不能使用任何库。
我检查负性的条件只是“ x <0”,不包括我的问题。我在Distinguish zero and negative zero中找到了一个有前途的解决方案。
这似乎可以解决我的问题:
double a = -0.0;
printf("%d\n", (*((long *)&a) == 0x8000000000000000));
我希望该程序打印1
,但是在我的程序中,当我在代码中执行此操作时,它会输出0
。我对此有一个问题的理解是:*((long *)&a)
使得数字可以与十六进制的数字相媲美。
答案 0 :(得分:7)
C数学库(标准库的一部分)提供a signbit
macro,这绝对是检查浮点数符号的最简单,最可移植的方法。如果您要避免使用库的要求是第三方库,那么它将满足您的目的。
示例:
#include <math.h>
#include <stdio.h>
void putsign(double d) {
if (signbit(d)) {
putchar('-');
} else {
putchar('+');
}
}
答案 1 :(得分:2)
这类似于我完成的Codewars Kata。诀窍是将要检查的数字除以负零,就像这样:
int isPositiveZero(double a) {
return 1/a == 1/0.0;
}
如果-infinity
为负零,则除法得到a
,如果infinity
为零,则除法得到a
。
如果您想按照自己的方式做,请尝试以下操作:
(*((long *)&a) & 0x8000000000000000)
请注意,这违反了严格的别名规则,这会导致未定义的行为。这意味着您的程序可以执行任何操作,从打印正确的结果到使计算机发芽并飞走。
如果您有math.h
可用,并且不反对使用标准C库中的宏,那么此解决方案(使用signbit
)也可以使用(并且更加可移植):
#include <math.h>
int isPositiveZero(double a) {
return a == 0.0 && !signbit(a);
}