mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-22 21:32:31 +00:00
Add long double printf formatting support
You can now easily print numbers that have 80 bits of precision. This change also imports many of the test vectors from the gdtoa codebase.
This commit is contained in:
parent
dae0583ee5
commit
1c387727fe
9 changed files with 808 additions and 287 deletions
|
@ -30,6 +30,20 @@
|
|||
|
||||
#define THREADS 16
|
||||
|
||||
#define DUB(i) (union Dub){i}.x
|
||||
|
||||
#define DUBBLE(a, b, c, d, e) \
|
||||
{ \
|
||||
{ 0x##e, 0x##d, 0x##c, 0x##b, 0x##a } \
|
||||
}
|
||||
|
||||
char buf[128];
|
||||
|
||||
union Dub {
|
||||
uint64_t i;
|
||||
double x;
|
||||
};
|
||||
|
||||
char *stack[THREADS];
|
||||
char tls[THREADS][64];
|
||||
|
||||
|
@ -60,3 +74,81 @@ TEST(dtoa, test) {
|
|||
_spinlock((int *)(tls[i] + 0x38));
|
||||
}
|
||||
}
|
||||
|
||||
static const struct {
|
||||
uint64_t i;
|
||||
const char *f;
|
||||
const char *s;
|
||||
} Vd[] = {
|
||||
{0x3ff3ae147ae147ae, "%.8a", "0x1.3ae147aep+0"}, //
|
||||
{0x3ff3ae147ae147ae, "%.7a", "0x1.3ae147bp+0"}, //
|
||||
{0x3ff3ae147ae147ae, "%.2a", "0x1.3bp+0"}, //
|
||||
};
|
||||
|
||||
TEST(printf, double) {
|
||||
int i;
|
||||
for (i = 0; i < ARRAYLEN(Vd); ++i) {
|
||||
++g_testlib_ran;
|
||||
snprintf(buf, sizeof(buf), Vd[i].f, DUB(Vd[i].i));
|
||||
if (strcmp(Vd[i].s, buf)) {
|
||||
fprintf(stderr,
|
||||
"TEST FAILED\n"
|
||||
"EXPECT_STREQ(%`'s, FMT(%`'s, DUB(0x%016lx)))\n"
|
||||
" BUT GOT %`'s\n",
|
||||
Vd[i].s, Vd[i].f, Vd[i].i, buf);
|
||||
testlib_incrementfailed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct {
|
||||
const char *s;
|
||||
const char *f;
|
||||
union {
|
||||
uint16_t i[5];
|
||||
long double x;
|
||||
} u;
|
||||
} Vx[] = {
|
||||
{"1.23000000000000000002", "%.21Lg", DUBBLE(3fff, 9d70, a3d7, a3d, 70a4)},
|
||||
{"123000000000000000000", "%.21Lg", DUBBLE(4041, d55e, f90a, 2da1, 8000)},
|
||||
{"1.22999999999999999997e-20", "%.21Lg",
|
||||
DUBBLE(3fbc, e857, 267b, b3a9, 84f2)},
|
||||
{"1.23456789000000000003", "%.21Lg", DUBBLE(3fff, 9e06, 5214, 1ef0, dbf6)},
|
||||
{"123456589000000000000", "%.21Lg", DUBBLE(4041, d629, bd33, 5cc, ba00)},
|
||||
{"1.22999999999999999999e+30", "%.21Lg",
|
||||
DUBBLE(4062, f865, 8274, 7dbc, 824a)},
|
||||
{"1.22999999999999999999e-30", "%.21Lg",
|
||||
DUBBLE(3f9b, c794, 337a, 8085, 54eb)},
|
||||
{"1.23456788999999999998e-20", "%.21Lg",
|
||||
DUBBLE(3fbc, e934, a38, f3d6, d352)},
|
||||
{"1.23456788999999999999e-30", "%.21Lg",
|
||||
DUBBLE(3f9b, c851, f19d, decc, a8fc)},
|
||||
{"1.23456789012345678899", "%.21Lg", DUBBLE(3fff, 9e06, 5214, 62cf, db8d)},
|
||||
{"1.22999999999999999997e+306", "%.21Lg",
|
||||
DUBBLE(43f7, e033, b668, e30f, a6d5)},
|
||||
{"1.23000000000000000002e-306", "%.21Lg",
|
||||
DUBBLE(3c06, dd1d, c2ed, 1cb7, 3f25)},
|
||||
{"1.23000000000000000002e-320", "%.21Lg",
|
||||
DUBBLE(3bd8, 9b98, c371, 844c, 3f1a)},
|
||||
{"0xap-3", "%.La", DUBBLE(3fff, 9d70, a3d7, a3d, 70a4)},
|
||||
{"0x9.d70a3d70a3d70a4p-3", "%.20La", DUBBLE(3fff, 9d70, a3d7, a3d, 70a4)},
|
||||
{"0x9.b18ab5df7180b6cp+88", "%La", DUBBLE(405a, 9b18, ab5d, f718, b6c)},
|
||||
{"0xa.fc6a015291b4024p+87", "%La", DUBBLE(4059, afc6, a015, 291b, 4024)},
|
||||
};
|
||||
|
||||
TEST(printf, longdouble) {
|
||||
int i;
|
||||
for (i = 0; i < ARRAYLEN(Vx); ++i) {
|
||||
++g_testlib_ran;
|
||||
snprintf(buf, sizeof(buf), Vx[i].f, Vx[i].u.x);
|
||||
if (strcmp(Vx[i].s, buf)) {
|
||||
fprintf(stderr,
|
||||
"TEST FAILED\n"
|
||||
"\t{%`'s, %`'s, DUBBLE(%x, %x, %x, %x, %x)}\n"
|
||||
"\t→%`'s\n",
|
||||
Vx[i].s, Vx[i].f, Vx[i].u.i[0], Vx[i].u.i[1], Vx[i].u.i[2],
|
||||
Vx[i].u.i[3], Vx[i].u.i[4], buf);
|
||||
testlib_incrementfailed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue