From cfd453d125d6b712257fd3d9aa95694d0c7dd435 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 6 Mar 2021 08:45:44 -0800 Subject: [PATCH] Add more real formatting tests See #61 --- libc/fmt/fmt.c | 143 ++++++++++++++----------- libc/stdio/stdio.h | 3 - test/libc/fmt/fmt_test.c | 199 +++++++++++++++++++++++++++++++++++ test/libc/fmt/realfmt_test.c | 68 ------------ third_party/gdtoa/dtoa.c | 4 +- 5 files changed, 283 insertions(+), 134 deletions(-) create mode 100644 test/libc/fmt/fmt_test.c delete mode 100644 test/libc/fmt/realfmt_test.c diff --git a/libc/fmt/fmt.c b/libc/fmt/fmt.c index 4d21be24..36d2f1e6 100644 --- a/libc/fmt/fmt.c +++ b/libc/fmt/fmt.c @@ -23,12 +23,23 @@ #include "libc/fmt/fmt.h" #include "libc/fmt/fmts.h" #include "libc/fmt/internal.h" +#include "libc/macros.internal.h" #include "libc/mem/mem.h" +#include "libc/nexgen32e/bsr.h" #include "libc/runtime/internal.h" #include "libc/str/str.h" #include "libc/sysv/errfuns.h" #include "third_party/gdtoa/gdtoa.h" +#define PUT(C) \ + do { \ + if (out(C, arg) == -1) { \ + return -1; \ + } \ + } while (0) + +static const char kSpecialFloats[2][2][4] = {{"INF", "inf"}, {"NAN", "nan"}}; + static int __fmt_atoi(const char **str) { int i; for (i = 0; '0' <= **str && **str <= '9'; ++*str) { @@ -107,11 +118,10 @@ static int __fmt_atoi(const char **str) { hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { union { double d; - unsigned int u[2]; + uint32_t u[2]; + uint64_t q; } pun; void *p; - char qchar; - char *s, *se; bool longdouble; long double ldbl; wchar_t charbuf[1]; @@ -119,6 +129,7 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { int (*out)(long, void *); unsigned char signbit, log2base; int c, d, k, w, i1, ui, bw, bex; + char *s, *q, *se, qchar, special[8]; int sgn, alt, sign, prec, prec1, flags, width, decpt, lasterr; lasterr = errno; @@ -128,7 +139,7 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { /* %[flags][width][.prec][length] */ if (*format != '%') { /* no */ - if (out(*format, arg) == -1) return -1; + PUT(*format); format++; continue; } else { @@ -308,6 +319,7 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { } break; + case 'F': case 'f': if (!(flags & FLAGS_PRECISION)) prec = 6; if (longdouble) { @@ -317,19 +329,25 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { } FormatDtoa: if (!weaken(__fmt_dtoa)) { - p = "nan"; - goto FormatString; + p = "?"; + goto FormatThatThing; } s = weaken(__fmt_dtoa)(pun.d, 3, prec, &decpt, &sgn, &se); if (decpt == 9999) { Format9999: - prec = alt = 0; - flags &= ~FLAGS_PRECISION; - if (*s == 'N') { - p = s; - goto FormatString; + p = q = memset(special, 0, sizeof(special)); + if (sgn) { + *q++ = '-'; + } else if (flags & FLAGS_PLUS) { + *q++ = '+'; + } else if (flags & FLAGS_SPACE) { + *q++ = ' '; } - decpt = strlen(s); + memcpy(q, kSpecialFloats[*s == 'N'][d >= 'a'], 4); + FormatThatThing: + prec = alt = 0; + flags &= ~(FLAGS_PRECISION | FLAGS_PLUS | FLAGS_SPACE); + goto FormatString; } FormatReal: if (sgn) sign = '-'; @@ -347,20 +365,21 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { } if (width > 0 && !(flags & FLAGS_LEFT)) { if (flags & FLAGS_ZEROPAD) { - if (sign) out(sign, arg); + if (sign) PUT(sign); sign = 0; - do out('0', arg); + do PUT('0'); while (--width > 0); - } else - do out(' ', arg); + } else { + do PUT(' '); while (--width > 0); + } } - if (sign) out(sign, arg); + if (sign) PUT(sign); if (decpt <= 0) { - out('0', arg); - if (prec > 0 || alt) out('.', arg); + PUT('0'); + if (prec > 0 || alt) PUT('.'); while (decpt < 0) { - out('0', arg); + PUT('0'); prec--; decpt++; } @@ -371,9 +390,9 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { } else { c = '0'; } - out(c, arg); + PUT(c); } while (--decpt > 0); - if (prec > 0 || alt) out('.', arg); + if (prec > 0 || alt) PUT('.'); } while (--prec >= 0) { if ((c = *s)) { @@ -381,10 +400,10 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { } else { c = '0'; } - out(c, arg); + PUT(c); } while (--width >= 0) { - out(' ', arg); + PUT(' '); } continue; @@ -398,8 +417,8 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { } if (prec < 0) prec = 0; if (!weaken(__fmt_dtoa)) { - p = "nan"; - goto FormatString; + p = "?"; + goto FormatThatThing; } s = weaken(__fmt_dtoa)(pun.d, prec ? 2 : 0, prec, &decpt, &sgn, &se); if (decpt == 9999) goto Format9999; @@ -408,7 +427,6 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { if (!prec) { prec = c; prec1 = c + (s[1] || alt ? 5 : 4); - /* %.0g gives 10 rather than 1e1 */ } if (decpt > -4 && decpt <= prec1) { if (alt) { @@ -434,8 +452,8 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { } if (prec < 0) prec = 0; if (!weaken(__fmt_dtoa)) { - p = "nan"; - goto FormatString; + p = "?"; + goto FormatThatThing; } s = weaken(__fmt_dtoa)(pun.d, 2, prec + 1, &decpt, &sgn, &se); if (decpt == 9999) goto Format9999; @@ -452,44 +470,44 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { } if (width > 0 && !(flags & FLAGS_LEFT)) { if (flags & FLAGS_ZEROPAD) { - if (sign) out(sign, arg); + if (sign) PUT(sign); sign = 0; - do out('0', arg); + do PUT('0'); while (--width > 0); } else { - do out(' ', arg); + do PUT(' '); while (--width > 0); } } - if (sign) out(sign, arg); - out(*s++, arg); - if (prec || alt) out('.', arg); + if (sign) PUT(sign); + PUT(*s++); + if (prec || alt) PUT('.'); while (--prec >= 0) { if ((c = *s)) { s++; } else { c = '0'; } - out(c, arg); + PUT(c); } - out(d, arg); + PUT(d); if (decpt < 0) { - out('-', arg); + PUT('-'); decpt = -decpt; } else { - out('+', arg); + PUT('+'); } for (c = 2, k = 10; 10 * k <= decpt; c++, k *= 10) { } for (;;) { i1 = decpt / k; - out(i1 + '0', arg); + PUT(i1 + '0'); if (--c <= 0) break; decpt -= i1 * k; decpt *= 10; } while (--width >= 0) { - out(' ', arg); + PUT(' '); } continue; @@ -507,12 +525,12 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { if ((pun.u[1] & 0x7ff00000) == 0x7ff00000) { goto FormatDtoa; } + if (pun.u[1] & 0x80000000) { + sign = '-'; + pun.u[1] &= 0x7fffffff; + } if (pun.d) { c = '1'; - if (pun.u[1] & 0x80000000) { - sign = '-'; - pun.u[1] &= 0x7fffffff; - } bex = (pun.u[1] >> 20) - 1023; pun.u[1] &= 0xfffff; if (bex == -1023) { @@ -595,49 +613,52 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { if (sign) --width; if (prec || alt) --width; } + if (pun.q && prec > 0) { + width -= ROUNDUP(bsrl(pun.q) + 1, 4) >> 2; + } if (width > 0 && !(flags & FLAGS_LEFT)) { if (flags & FLAGS_ZEROPAD) { if (sign) { - out(sign, arg); + PUT(sign); sign = 0; } - do out('0', arg); + do PUT('0'); while (--width > 0); } else { - do out(' ', arg); + do PUT(' '); while (--width > 0); } } - if (sign) out(sign, arg); - out('0', arg); - out(alphabet[17], arg); - out(c, arg); - if (prec > 0 || alt) out('.', arg); + if (sign) PUT(sign); + PUT('0'); + PUT(alphabet[17]); + PUT(c); + if (prec > 0 || alt) PUT('.'); if (prec > 0) { if ((i1 = prec) > 5) i1 = 5; prec -= i1; do { - out(alphabet[(pun.u[1] >> 16) & 0xf], arg); + PUT(alphabet[(pun.u[1] >> 16) & 0xf]); pun.u[1] <<= 4; } while (--i1 > 0); while (prec > 0) { --prec; - out(alphabet[(pun.u[0] >> 28) & 0xf], arg); + PUT(alphabet[(pun.u[0] >> 28) & 0xf]); pun.u[0] <<= 4; } } - out(alphabet[16], arg); + PUT(alphabet[16]); if (bex < 0) { - out('-', arg); + PUT('-'); bex = -bex; } else { - out('+', arg); + PUT('+'); } for (c = 1; 10 * c <= bex; c *= 10) { } for (;;) { i1 = bex / c; - out('0' + i1, arg); + PUT('0' + i1); if (!--bw) break; bex -= i1 * c; bex *= 10; @@ -645,11 +666,11 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) { continue; case '%': - if (out('%', arg) == -1) return -1; + PUT('%'); break; default: - if (out(format[-1], arg) == -1) return -1; + PUT(format[-1]); break; } } diff --git a/libc/stdio/stdio.h b/libc/stdio/stdio.h index abd7549c..e9598874 100644 --- a/libc/stdio/stdio.h +++ b/libc/stdio/stdio.h @@ -8,9 +8,6 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -int Printf(const char *, ...); -int Sprintf(char *, const char *, ...); - /*───────────────────────────────────────────────────────────────────────────│─╗ │ cosmopolitan § standard i/o ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ diff --git a/test/libc/fmt/fmt_test.c b/test/libc/fmt/fmt_test.c new file mode 100644 index 00000000..7768f0e6 --- /dev/null +++ b/test/libc/fmt/fmt_test.c @@ -0,0 +1,199 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2021 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/fmt/fmt.h" +#include "libc/math.h" +#include "libc/runtime/gc.h" +#include "libc/str/str.h" +#include "libc/testlib/testlib.h" +#include "libc/x/x.h" + +TEST(RealFormatting, g) { + EXPECT_STREQ("1", gc(xasprintf("%g", 1.))); + EXPECT_STREQ("-1", gc(xasprintf("%g", -1.))); + EXPECT_STREQ("10", gc(xasprintf("%g", 10.))); + EXPECT_STREQ("10", gc(xasprintf("%.0g", 10.))); + EXPECT_STREQ("-10", gc(xasprintf("%g", -10.))); + EXPECT_STREQ("-10", gc(xasprintf("%.0g", -10.))); + EXPECT_STREQ("1e+100", gc(xasprintf("%g", 1e100))); + EXPECT_STREQ("1e-100", gc(xasprintf("%g", 1e-100))); + EXPECT_STREQ("-1e-100", gc(xasprintf("%g", -1e-100))); + EXPECT_STREQ("3.14159", gc(xasprintf("%g", 0x1.921fb54442d1846ap+1))); + EXPECT_STREQ("0", gc(xasprintf("%g", 0.))); + EXPECT_STREQ("-0", gc(xasprintf("%g", -0.))); + EXPECT_STREQ("nan", gc(xasprintf("%g", NAN))); + EXPECT_STREQ("-nan", gc(xasprintf("%g", -NAN))); + EXPECT_STREQ("inf", gc(xasprintf("%g", INFINITY))); + EXPECT_STREQ("-inf", gc(xasprintf("%g", -INFINITY))); + EXPECT_STREQ("2.22507e-308", gc(xasprintf("%g", __DBL_MIN__))); + EXPECT_STREQ("1.79769e+308", gc(xasprintf("%g", __DBL_MAX__))); + EXPECT_STREQ("0", gc(xasprintf("%G", 0.))); + EXPECT_STREQ("-0", gc(xasprintf("%G", -0.))); + EXPECT_STREQ("NAN", gc(xasprintf("%G", NAN))); + EXPECT_STREQ("-NAN", gc(xasprintf("%G", -NAN))); + EXPECT_STREQ("INF", gc(xasprintf("%G", INFINITY))); + EXPECT_STREQ("-INF", gc(xasprintf("%G", -INFINITY))); + EXPECT_STREQ("2.22507E-308", gc(xasprintf("%G", __DBL_MIN__))); + EXPECT_STREQ("1.79769E+308", gc(xasprintf("%G", __DBL_MAX__))); + EXPECT_STREQ(" 0", gc(xasprintf("%13g", 0.))); + EXPECT_STREQ(" -0", gc(xasprintf("%13g", -0.))); + EXPECT_STREQ(" nan", gc(xasprintf("%13g", NAN))); + EXPECT_STREQ(" -nan", gc(xasprintf("%13g", -NAN))); + EXPECT_STREQ(" inf", gc(xasprintf("%13g", INFINITY))); + EXPECT_STREQ(" -inf", gc(xasprintf("%13g", -INFINITY))); + EXPECT_STREQ(" 2.22507e-308", gc(xasprintf("%13g", __DBL_MIN__))); + EXPECT_STREQ(" 1.79769e+308", gc(xasprintf("%13g", __DBL_MAX__))); + EXPECT_STREQ(" 0", gc(xasprintf("%13G", 0.))); + EXPECT_STREQ(" -0", gc(xasprintf("%13G", -0.))); + EXPECT_STREQ(" NAN", gc(xasprintf("%13G", NAN))); + EXPECT_STREQ(" -NAN", gc(xasprintf("%13G", -NAN))); + EXPECT_STREQ(" INF", gc(xasprintf("%13G", INFINITY))); + EXPECT_STREQ(" -INF", gc(xasprintf("%13G", -INFINITY))); + EXPECT_STREQ(" 2.22507E-308", gc(xasprintf("%13G", __DBL_MIN__))); + EXPECT_STREQ(" 1.79769E+308", gc(xasprintf("%13G", __DBL_MAX__))); +} + +TEST(RealFormatting, f) { + EXPECT_STREQ("3.141593", gc(xasprintf("%f", 0x1.921fb54442d1846ap+1))); + EXPECT_STREQ("3.1415926535897931", + gc(xasprintf("%.16f", 0x1.921fb54442d1846ap+1))); + EXPECT_STREQ("100000000000000001590289110975991804683608085639452813" + "89781327557747838772170381060813469985856815104.000000", + gc(xasprintf("%f", 1e100))); + EXPECT_STREQ("0.000000", gc(xasprintf("%f", 0.))); + EXPECT_STREQ("-0.000000", gc(xasprintf("%f", -0.))); + EXPECT_STREQ("nan", gc(xasprintf("%f", NAN))); + EXPECT_STREQ("-nan", gc(xasprintf("%f", -NAN))); + EXPECT_STREQ("inf", gc(xasprintf("%f", INFINITY))); + EXPECT_STREQ("-inf", gc(xasprintf("%f", -INFINITY))); + EXPECT_STREQ("0.000000", gc(xasprintf("%f", __DBL_MIN__))); + EXPECT_STREQ( + "179769313486231570814527423731704356798070567525844996598917476803157260" + "780028538760589558632766878171540458953514382464234321326889464182768467" + "546703537516986049910576551282076245490090389328944075868508455133942304" + "583236903222948165808559332123348274797826204144723168738177180919299881" + "250404026184124858368.000000", + gc(xasprintf("%f", __DBL_MAX__))); + EXPECT_STREQ("0.000000", gc(xasprintf("%F", 0.))); + EXPECT_STREQ("-0.000000", gc(xasprintf("%F", -0.))); + EXPECT_STREQ("NAN", gc(xasprintf("%F", NAN))); + EXPECT_STREQ("-NAN", gc(xasprintf("%F", -NAN))); + EXPECT_STREQ("INF", gc(xasprintf("%F", INFINITY))); + EXPECT_STREQ("-INF", gc(xasprintf("%F", -INFINITY))); + EXPECT_STREQ("0.000000", gc(xasprintf("%F", __DBL_MIN__))); + EXPECT_STREQ( + "179769313486231570814527423731704356798070567525844996598917476803157260" + "780028538760589558632766878171540458953514382464234321326889464182768467" + "546703537516986049910576551282076245490090389328944075868508455133942304" + "583236903222948165808559332123348274797826204144723168738177180919299881" + "250404026184124858368.000000", + gc(xasprintf("%F", __DBL_MAX__))); + EXPECT_STREQ(" 0.000000", gc(xasprintf("%10f", 0.))); + EXPECT_STREQ(" -0.000000", gc(xasprintf("%10f", -0.))); + EXPECT_STREQ(" nan", gc(xasprintf("%10f", NAN))); + EXPECT_STREQ(" -nan", gc(xasprintf("%10f", -NAN))); + EXPECT_STREQ(" inf", gc(xasprintf("%10f", INFINITY))); + EXPECT_STREQ(" -inf", gc(xasprintf("%10f", -INFINITY))); + EXPECT_STREQ(" 0.000000", gc(xasprintf("%10f", __DBL_MIN__))); + EXPECT_STREQ( + "179769313486231570814527423731704356798070567525844996598917476803157260" + "780028538760589558632766878171540458953514382464234321326889464182768467" + "546703537516986049910576551282076245490090389328944075868508455133942304" + "583236903222948165808559332123348274797826204144723168738177180919299881" + "250404026184124858368.000000", + gc(xasprintf("%10f", __DBL_MAX__))); + EXPECT_STREQ(" 0.000000", gc(xasprintf("%10F", 0.))); + EXPECT_STREQ(" -0.000000", gc(xasprintf("%10F", -0.))); + EXPECT_STREQ(" NAN", gc(xasprintf("%10F", NAN))); + EXPECT_STREQ(" -NAN", gc(xasprintf("%10F", -NAN))); + EXPECT_STREQ(" INF", gc(xasprintf("%10F", INFINITY))); + EXPECT_STREQ(" -INF", gc(xasprintf("%10F", -INFINITY))); + EXPECT_STREQ(" 0.000000", gc(xasprintf("%10F", __DBL_MIN__))); + EXPECT_STREQ( + "179769313486231570814527423731704356798070567525844996598917476803157260" + "780028538760589558632766878171540458953514382464234321326889464182768467" + "546703537516986049910576551282076245490090389328944075868508455133942304" + "583236903222948165808559332123348274797826204144723168738177180919299881" + "250404026184124858368.000000", + gc(xasprintf("%10F", __DBL_MAX__))); +} + +TEST(RealFormatting, e) { + EXPECT_STREQ("3.14159", gc(xasprintf("%g", 0x1.921fb54442d1846ap+1))); + EXPECT_STREQ("3.141592653589793", + gc(xasprintf("%.16g", 0x1.921fb54442d1846ap+1))); + EXPECT_STREQ("1.000000e+100", gc(xasprintf("%e", 1e100))); + EXPECT_STREQ("1.000000E+100", gc(xasprintf("%E", 1e100))); + EXPECT_STREQ(" 0.000000e+00", gc(xasprintf("%24e", 0.))); + EXPECT_STREQ(" -0.000000e+00", gc(xasprintf("%24e", -0.))); + EXPECT_STREQ(" nan", gc(xasprintf("%24e", NAN))); + EXPECT_STREQ(" -nan", gc(xasprintf("%24e", -NAN))); + EXPECT_STREQ(" inf", gc(xasprintf("%24e", INFINITY))); + EXPECT_STREQ(" -inf", gc(xasprintf("%24e", -INFINITY))); + EXPECT_STREQ(" 2.225074e-308", gc(xasprintf("%24e", __DBL_MIN__))); + EXPECT_STREQ(" 1.797693e+308", gc(xasprintf("%24e", __DBL_MAX__))); + EXPECT_STREQ(" 0.000000E+00", gc(xasprintf("%24E", 0.))); + EXPECT_STREQ(" -0.000000E+00", gc(xasprintf("%24E", -0.))); + EXPECT_STREQ(" NAN", gc(xasprintf("%24E", NAN))); + EXPECT_STREQ(" -NAN", gc(xasprintf("%24E", -NAN))); + EXPECT_STREQ(" INF", gc(xasprintf("%24E", INFINITY))); + EXPECT_STREQ(" -INF", gc(xasprintf("%24E", -INFINITY))); + EXPECT_STREQ(" 2.225074E-308", gc(xasprintf("%24E", __DBL_MIN__))); + EXPECT_STREQ(" 1.797693E+308", gc(xasprintf("%24E", __DBL_MAX__))); + EXPECT_STREQ(" +0.000000e+00", gc(xasprintf("%+24e", 0.))); + EXPECT_STREQ(" -0.000000e+00", gc(xasprintf("%+24e", -0.))); + EXPECT_STREQ(" +nan", gc(xasprintf("%+24e", NAN))); + EXPECT_STREQ(" -nan", gc(xasprintf("%+24e", -NAN))); + EXPECT_STREQ(" +inf", gc(xasprintf("%+24e", INFINITY))); + EXPECT_STREQ(" -inf", gc(xasprintf("%+24e", -INFINITY))); + EXPECT_STREQ(" +2.225074e-308", gc(xasprintf("%+24e", __DBL_MIN__))); + EXPECT_STREQ(" +1.797693e+308", gc(xasprintf("%+24e", __DBL_MAX__))); + EXPECT_STREQ(" +0.000000E+00", gc(xasprintf("%+24E", 0.))); + EXPECT_STREQ(" -0.000000E+00", gc(xasprintf("%+24E", -0.))); + EXPECT_STREQ(" +NAN", gc(xasprintf("%+24E", NAN))); + EXPECT_STREQ(" -NAN", gc(xasprintf("%+24E", -NAN))); + EXPECT_STREQ(" +INF", gc(xasprintf("%+24E", INFINITY))); + EXPECT_STREQ(" -INF", gc(xasprintf("%+24E", -INFINITY))); + EXPECT_STREQ(" +2.225074E-308", gc(xasprintf("%+24E", __DBL_MIN__))); + EXPECT_STREQ(" +1.797693E+308", gc(xasprintf("%+24E", __DBL_MAX__))); +} + +TEST(RealFormatting, a) { + EXPECT_STREQ("0x1.921fb54442d18p+1", + gc(xasprintf("%a", 0x1.921fb54442d1846ap+1))); + EXPECT_STREQ("0X1.921FB54442D18P+1", + gc(xasprintf("%A", 0x1.921fb54442d1846ap+1))); + EXPECT_STREQ(" 0x0p+0", gc(xasprintf("%24a", 0.))); + EXPECT_STREQ(" -0x0p+0", gc(xasprintf("%24a", -0.))); + EXPECT_STREQ(" nan", gc(xasprintf("%24a", NAN))); + EXPECT_STREQ(" -nan", gc(xasprintf("%24a", -NAN))); + EXPECT_STREQ(" inf", gc(xasprintf("%24a", INFINITY))); + EXPECT_STREQ(" -inf", gc(xasprintf("%24a", -INFINITY))); + EXPECT_STREQ(" 0x1p-1022", gc(xasprintf("%24a", __DBL_MIN__))); + EXPECT_STREQ(" 0x1.fffffffffffffp+1023", gc(xasprintf("%24a", __DBL_MAX__))); + EXPECT_STREQ(" 0X0P+0", gc(xasprintf("%24A", 0.))); + EXPECT_STREQ(" -0X0P+0", gc(xasprintf("%24A", -0.))); + EXPECT_STREQ(" NAN", gc(xasprintf("%24A", NAN))); + EXPECT_STREQ(" -NAN", gc(xasprintf("%24A", -NAN))); + EXPECT_STREQ(" INF", gc(xasprintf("%24A", INFINITY))); + EXPECT_STREQ(" -INF", gc(xasprintf("%24A", -INFINITY))); + EXPECT_STREQ(" 0X1P-1022", gc(xasprintf("%24A", __DBL_MIN__))); + EXPECT_STREQ(" 0X1.FFFFFFFFFFFFFP+1023", gc(xasprintf("%24A", __DBL_MAX__))); + EXPECT_STREQ(" 0X1.E9A488E8A71DEP+14", gc(xasprintf("%24A", 31337.1337))); + EXPECT_STREQ(" -0X1.E9A488E8A71DEP+14", gc(xasprintf("%24A", -31337.1337))); +} diff --git a/test/libc/fmt/realfmt_test.c b/test/libc/fmt/realfmt_test.c deleted file mode 100644 index 05881ab5..00000000 --- a/test/libc/fmt/realfmt_test.c +++ /dev/null @@ -1,68 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2021 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/fmt.h" -#include "libc/math.h" -#include "libc/runtime/gc.h" -#include "libc/testlib/testlib.h" -#include "libc/x/x.h" - -TEST(RealFormatting, g) { - EXPECT_STREQ("nan", gc(xasprintf("%g", NAN))); - EXPECT_STREQ("-nan", gc(xasprintf("%g", -NAN))); - EXPECT_STREQ("inf", gc(xasprintf("%g", INFINITY))); - EXPECT_STREQ("-inf", gc(xasprintf("%g", -INFINITY))); - EXPECT_STREQ("0", gc(xasprintf("%g", 0.))); - EXPECT_STREQ("-0", gc(xasprintf("%g", -0.))); - EXPECT_STREQ("1", gc(xasprintf("%g", 1.))); - EXPECT_STREQ("-1", gc(xasprintf("%g", -1.))); - EXPECT_STREQ("10", gc(xasprintf("%g", 10.))); - EXPECT_STREQ("10", gc(xasprintf("%.0g", 10.))); - EXPECT_STREQ("-10", gc(xasprintf("%g", -10.))); - EXPECT_STREQ("-10", gc(xasprintf("%.0g", -10.))); - EXPECT_STREQ(" -10", gc(xasprintf("%10g", -10.))); - EXPECT_STREQ(" -10", gc(xasprintf("%*g", 10, -10.))); - EXPECT_STREQ("1e+100", gc(xasprintf("%g", 1e100))); - EXPECT_STREQ("1e-100", gc(xasprintf("%g", 1e-100))); - EXPECT_STREQ("-1e-100", gc(xasprintf("%g", -1e-100))); - EXPECT_STREQ("3.14159", gc(xasprintf("%g", 0x1.921fb54442d1846ap+1))); -} - -TEST(RealFormatting, f) { - EXPECT_STREQ("3.141593", gc(xasprintf("%f", 0x1.921fb54442d1846ap+1))); - EXPECT_STREQ("3.1415926535897931", - gc(xasprintf("%.16f", 0x1.921fb54442d1846ap+1))); - EXPECT_STREQ("100000000000000001590289110975991804683608085639452813" - "89781327557747838772170381060813469985856815104.000000", - gc(xasprintf("%f", 1e100))); -} - -TEST(RealFormatting, e) { - EXPECT_STREQ("3.14159", gc(xasprintf("%g", 0x1.921fb54442d1846ap+1))); - EXPECT_STREQ("3.141592653589793", - gc(xasprintf("%.16g", 0x1.921fb54442d1846ap+1))); - EXPECT_STREQ("1.000000e+100", gc(xasprintf("%e", 1e100))); - EXPECT_STREQ("1.000000E+100", gc(xasprintf("%E", 1e100))); -} - -TEST(RealFormatting, a) { - EXPECT_STREQ("0x1.921fb54442d18p+1", - gc(xasprintf("%a", 0x1.921fb54442d1846ap+1))); - EXPECT_STREQ("0X1.921FB54442D18P+1", - gc(xasprintf("%A", 0x1.921fb54442d1846ap+1))); -} diff --git a/third_party/gdtoa/dtoa.c b/third_party/gdtoa/dtoa.c index da35f8b9..7884a8f8 100644 --- a/third_party/gdtoa/dtoa.c +++ b/third_party/gdtoa/dtoa.c @@ -168,9 +168,9 @@ dtoa(double d0, int mode, int ndigits, int *decpt, int *sign, char **rve) *decpt = 9999; #ifdef IEEE_Arith if (!word1(&d) && !(word0(&d) & 0xfffff)) - return nrv_alloc("inf", rve, 8 MTb); + return nrv_alloc("Infinity", rve, 8 MTb); #endif - return nrv_alloc("nan", rve, 3 MTb); + return nrv_alloc("NaN", rve, 3 MTb); } #endif #ifdef IBM