ref: b002d95459ec9dbd439db8090694abdb885ad4a2
parent: 646fc62b89f10a9de203d3989a7e9a140557f88f
author: Rangi <remy.oukaour+rangi42@gmail.com>
date: Wed Oct 27 16:24:54 EDT 2021
Fix precison of fixed-point formatting Fixes #908
--- a/src/asm/format.c
+++ b/src/asm/format.c
@@ -228,21 +228,13 @@
/* 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
--- a/test/asm/fixed-point-precision.asm
+++ b/test/asm/fixed-point-precision.asm
@@ -9,3 +9,6 @@
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})"
--- 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)
--- 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 > < hello>
<300 >