From cc23b9bf4998d93b8de040f7a5a95a1f3b525b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sigrid=20Solveig=20Hafl=C3=ADnud=C3=B3ttir?= Date: Thu, 9 Mar 2023 11:29:12 +0000 Subject: print, strtod: fix -0 and -NaN, respect verb flags when formatting --- sys/src/libc/fmt/fltfmt.c | 39 +++++++++++++++++++++------------------ sys/src/libc/port/strtod.c | 30 ++++++++++++++++++------------ 2 files changed, 39 insertions(+), 30 deletions(-) (limited to 'sys/src') diff --git a/sys/src/libc/fmt/fltfmt.c b/sys/src/libc/fmt/fltfmt.c index b0fcc3938..77638282c 100644 --- a/sys/src/libc/fmt/fltfmt.c +++ b/sys/src/libc/fmt/fltfmt.c @@ -11,6 +11,8 @@ enum NEXP10 = 308, }; +#define SIGN (1<<31) + static int xadd(char *a, int n, int v) { @@ -55,34 +57,26 @@ static void xdtoa(Fmt *fmt, char *s2, double f) { char s1[NSIGNIF+10]; + FPdbleword a; double g, h; int e, d, i, n; - int c1, c2, c3, c4, ucase, sign, chr, prec; + int c1, c2, c3, c4, ucase, sign, chr, prec, isnan, isinf; prec = FDEFLT; if(fmt->flags & FmtPrec) prec = fmt->prec; if(prec > FDIGIT) prec = FDIGIT; - if(isNaN(f)) { - strcpy(s2, "NaN"); - return; - } - if(isInf(f, 1)) { - strcpy(s2, "+Inf"); - return; - } - if(isInf(f, -1)) { - strcpy(s2, "-Inf"); - return; - } - sign = 0; - if(f < 0) { - f = -f; - sign++; - } + a.x = f; + sign = a.hi & SIGN; ucase = 0; chr = fmt->r; + isnan = isNaN(f); + isinf = isInf(f, 0); + if(isnan || isinf) + goto found; + if(sign) + f = -f; if(isupper(chr)) { ucase = 1; chr = tolower(chr); @@ -180,6 +174,15 @@ found: else if(fmt->flags & FmtSpace) s2[d++] = ' '; + if(isnan){ + strcpy(s2+d, "NaN"); + return; + } + if(isinf){ + strcpy(s2+d, "Inf"); + return; + } + /* * copy into final place * c1 digits of leading '0' diff --git a/sys/src/libc/port/strtod.c b/sys/src/libc/port/strtod.c index c8756d90f..1bd47e185 100644 --- a/sys/src/libc/port/strtod.c +++ b/sys/src/libc/port/strtod.c @@ -40,6 +40,8 @@ enum S7, // _+#.#e+# #S7 }; +#define SIGN (1<<31) + static int xcmp(char*, char*); static int fpcmp(char*, ulong*); static void frnorm(ulong*); @@ -60,7 +62,7 @@ strtod(char *as, char **aas) { int na, ona, ex, dp, bp, c, i, flag, state; ulong low[Prec], hig[Prec], mid[Prec], num, den; - double d; + FPdbleword d; char *s, a[Ndig]; flag = 0; // Fsign, Fesign, Fdpoint @@ -150,12 +152,12 @@ strtod(char *as, char **aas) */ switch(state) { case S0: + case S1: if(xcmp(s, "nan") == 0) { if(aas != nil) *aas = s+3; goto retnan; } - case S1: if(xcmp(s, "infinity") == 0) { if(aas != nil) *aas = s+8; @@ -283,24 +285,28 @@ strtod(char *as, char **aas) mid[Prec-1] += Sigbit; frnorm(mid); } - d = 0; + d.x = 0; for(i=0; i