diff options
author | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2014-12-15 16:13:01 +0100 |
---|---|---|
committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2014-12-15 17:27:49 +0100 |
commit | f8e05f3850e51673522216f23533bf7146359dcd (patch) | |
tree | 388ffe38b5648af914bf0c9272f1768982f441bf /libc | |
parent | 067637375658047d70c296606ae17ef0bc86499d (diff) |
stdio: Fix printing 0.0
We were relying on FE_DIVBYZERO being turned off when printing
"%f", +-.0
Avoid the whole issue by looking at the sign-bit (in a rough
approximation).
Note that we do not handle gracefully:
printf ("\n%llf\n", -0.0);
printf ("\n%llf\n", 0.0);
nor %Lf for both when NOT cast to long double. Avoiding an FPE due to
broken numbers like these does not make sense to me.
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Diffstat (limited to 'libc')
-rw-r--r-- | libc/stdio/_fpmaxtostr.c | 13 |
1 files changed, 7 insertions, 6 deletions
diff --git a/libc/stdio/_fpmaxtostr.c b/libc/stdio/_fpmaxtostr.c index f7ea792c4..35805844a 100644 --- a/libc/stdio/_fpmaxtostr.c +++ b/libc/stdio/_fpmaxtostr.c @@ -45,11 +45,6 @@ */ #define isnan(x) ((x) != (x)) -/* Without seminumerical functions to examine the sign bit, this is - * about the best we can do to test for '-0'. - */ -#define zeroisnegative(x) ((1./(x)) < 0) - /*****************************************************************************/ /* Don't change anything that follows peroid!!! ;-) */ /*****************************************************************************/ @@ -262,7 +257,13 @@ ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info, if (x == 0) { /* Handle 0 now to avoid false positive. */ #ifdef __UCLIBC_HAVE_SIGNED_ZERO__ - if (zeroisnegative(x)) { /* Handle 'signed' zero. */ + union { + double x; + struct { + unsigned int l1, l2; + } i; + } u = {x}; + if (u.i.l1 ^ u.i.l2) { /* Handle 'signed' zero. */ *sign_str = '-'; } #endif /* __UCLIBC_HAVE_SIGNED_ZERO__ */ |