kan*_*aka 4 c math floating-point
#include <stdio.h>
#include <math.h>
int main () {
float a = 0.0, b = -0.0;
printf("fmax(%f, %f) = %f\n", a, b, fmax(a, b));
}
Run Code Online (Sandbox Code Playgroud)
我得到以下结果:
gcc f.c -o f -lm
./f
fmax(0.000000, -0.000000) = -0.000000
Run Code Online (Sandbox Code Playgroud)
fmax手册页中未记录此(错误)行为.对它有合理的解释吗?是否有一个干净(简洁)的解决方法?另外,如果两者都是-0.0,我想得到-0.0作为最大值.
"问题"就是这样a == b.标志无关紧要,因为尾数(标志放在一边)纯粹是0.我得到了0x80000000vs0
所以fmax只是检查是否a < b或b < a(取决于实现),都是假的,所以无论答案是潜在的匹配.
在我的gcc版本,我得到fmax(0.0,-0.0)的0.0,不过fmax(-0.0,0.0)是-0.0.
我尝试了一个完整的解决方法,memcmp用于在0结果的情况下比较二进制数据.
如建议的那样更好,使用signbit哪个测试,如果数字设置为负位(无论值如何):
#include <stdio.h>
#include <math.h>
#include <string.h>
float my_fmax(float a,float b)
{
float result = fmax(a,b);
if ((result==0) && (a==b))
{
/* equal values and both zero
the only case of potential wrong selection of the negative
value. Only in that case, we tamper with the result of fmax,
and just return a unless a has negative bit set */
result = signbit(a) ? b : a;
}
return result;
}
int main () {
float a = -0.0, b = 0.0;
printf("fmax(%f, %f) = %f\n", a,b, my_fmax(a, b));
a = 0.0;
printf("fmax(%f, %f) = %f\n", a,b, my_fmax(a, b));
a = b = -0.0;
printf("fmax(%f, %f) = %f\n", a,b, my_fmax(a, b));
a = 1.0;
printf("fmax(%f, %f) = %f\n", a,b, my_fmax(a, b));
a = -1.0;
printf("fmax(%f, %f) = %f\n", a,b, my_fmax(a, b));
b = 0.0;
printf("fmax(%f, %f) = %f\n", a,b, my_fmax(a, b));
}
Run Code Online (Sandbox Code Playgroud)
结果(我想我涵盖了所有案例):
fmax(-0.000000, 0.000000) = 0.000000
fmax(0.000000, 0.000000) = 0.000000
fmax(-0.000000, -0.000000) = -0.000000
fmax(1.000000, -0.000000) = 1.000000
fmax(-1.000000, -0.000000) = -0.000000
fmax(-1.000000, 0.000000) = 0.000000
Run Code Online (Sandbox Code Playgroud)