summaryrefslogtreecommitdiff
path: root/libc/stdio/_fpmaxtostr.c
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2014-12-15 16:13:01 +0100
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2014-12-15 17:27:49 +0100
commitf8e05f3850e51673522216f23533bf7146359dcd (patch)
tree388ffe38b5648af914bf0c9272f1768982f441bf /libc/stdio/_fpmaxtostr.c
parent067637375658047d70c296606ae17ef0bc86499d (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/stdio/_fpmaxtostr.c')
-rw-r--r--libc/stdio/_fpmaxtostr.c13
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__ */