mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +00:00
parent
6fa049c9c7
commit
cfd453d125
5 changed files with 283 additions and 134 deletions
143
libc/fmt/fmt.c
143
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,9 +8,6 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int Printf(const char *, ...);
|
||||
int Sprintf(char *, const char *, ...);
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § standard i/o ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
|
199
test/libc/fmt/fmt_test.c
Normal file
199
test/libc/fmt/fmt_test.c
Normal file
|
@ -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)));
|
||||
}
|
|
@ -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)));
|
||||
}
|
4
third_party/gdtoa/dtoa.c
vendored
4
third_party/gdtoa/dtoa.c
vendored
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue