#include <stdio.h> #include <math.h> int main () { float = 0.0, b = -0.0; printf("fmax(%f, %f) = %f\n", a, b, fmax(a, b)); }
i following result:
gcc f.c -o f -lm ./f fmax(0.000000, -0.000000) = -0.000000
this (mis)behavior not documented in fmax man page. there reasonable explanation it? , there clean (concise) workaround? also, if both -0.0, -0.0 max.
the "problem" a == b
. sign doesn't matter because mantissa (sign put aside) purely 0. 0x80000000
vs 0
so fmax
checks if a < b
or b < a
(depending on implementation), , both false, either answer potential match.
on gcc version fmax(0.0,-0.0)
@ 0.0
, fmax(-0.0,0.0)
-0.0
.
my attempt @ full workaround, using memcmp
compare data binary wise in case of 0 result.
even better suggested, using signbit
tests if number has negative bit set (regardless of value):
#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 , both 0 case of potential wrong selection of negative value. in case, tamper result of fmax, , return unless has negative bit set */ result = signbit(a) ? b : a; } return result; } int main () { float = -0.0, b = 0.0; printf("fmax(%f, %f) = %f\n", a,b, my_fmax(a, b)); = 0.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)); = 1.0; printf("fmax(%f, %f) = %f\n", a,b, my_fmax(a, b)); = -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)); }
result (i think covered cases):
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
Comments
Post a Comment