From b002d95459ec9dbd439db8090694abdb885ad4a2 Mon Sep 17 00:00:00 2001 From: Rangi Date: Wed, 27 Oct 2021 20:24:54 -0400 Subject: [PATCH] Fix precison of fixed-point formatting Fixes #908 --- src/asm/format.c | 20 ++++++-------------- test/asm/fixed-point-precision.asm | 3 +++ test/asm/fixed-point-precision.out | 5 +++-- test/asm/string-formatting.out | 2 +- 4 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/asm/format.c b/src/asm/format.c index 39b6a5b0..c4c7e947 100644 --- a/src/asm/format.c +++ b/src/asm/format.c @@ -228,21 +228,13 @@ void fmt_PrintNumber(char *buf, size_t bufLen, struct FormatSpec const *fmt, uin /* Default fractional width (C's is 6 for "%f"; here 5 is enough) */ size_t fracWidth = fmt->hasFrac ? fmt->fracWidth : 5; - if (fracWidth) { - if (fracWidth > 255) { - error("Fractional width %zu too long, limiting to 255\n", - fracWidth); - fracWidth = 255; - } - - char spec[16]; /* Max "%" + 5-char PRIu32 + ".%0255.f" + terminator */ - - snprintf(spec, sizeof(spec), "%%" PRIu32 ".%%0%zu.f", fracWidth); - snprintf(valueBuf, sizeof(valueBuf), spec, value >> 16, - (value % 65536) / 65536.0 * pow(10, fracWidth) + 0.5); - } else { - snprintf(valueBuf, sizeof(valueBuf), "%" PRIu32, value >> 16); + if (fracWidth > 255) { + error("Fractional width %zu too long, limiting to 255\n", + fracWidth); + fracWidth = 255; } + + snprintf(valueBuf, sizeof(valueBuf), "%.*f", (int)fracWidth, value / 65536.0); } else { char const *spec = fmt->type == 'd' ? "%" PRId32 : fmt->type == 'u' ? "%" PRIu32 diff --git a/test/asm/fixed-point-precision.asm b/test/asm/fixed-point-precision.asm index 9ae79d83..84438ec2 100644 --- a/test/asm/fixed-point-precision.asm +++ b/test/asm/fixed-point-precision.asm @@ -9,3 +9,6 @@ pr = 16.12 fl = 6.283185 println "`6.283185`: {.6f:fl} -> ${08x:fl}" + +fr = MUL(20.0, 0.32) + println "32% of 20 = {f:fr} (~{.2f:fr}) (~~{.0f:fr})" diff --git a/test/asm/fixed-point-precision.out b/test/asm/fixed-point-precision.out index ed6a3361..ad3b15e3 100644 --- a/test/asm/fixed-point-precision.out +++ b/test/asm/fixed-point-precision.out @@ -1,5 +1,6 @@ -`3.1`: 3.100007 -> $0003199a +`3.1`: 3.100006 -> $0003199a `5.2`: 5.199997 -> $00053333 `MUL`: 16.120026 -> $00101eba -`16.12`: 16.119996 -> $00101eb8 +`16.12`: 16.119995 -> $00101eb8 `6.283185`: 6.283188 -> $0006487f +32% of 20 = 6.40015 (~6.40) (~~6) diff --git a/test/asm/string-formatting.out b/test/asm/string-formatting.out index 7072d1c5..a27663a9 100644 --- a/test/asm/string-formatting.out +++ b/test/asm/string-formatting.out @@ -1,5 +1,5 @@ < 300 > <+00300> < 12c> < %100101100> <4294967254> <-42> <&000037777777726> -<3.14159> <-00123> <-123.0455932618> +<3.14159> <-00123> <-123.0455932617> < hello> <300 >