[Nickle] nickle: Branch 'master' - 2 commits
Keith Packard
keithp at keithp.com
Sun Dec 8 14:11:21 PST 2024
float.c | 3 +++
test/Makefile.am | 1 +
test/fround.5c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
test/meson.build | 1 +
4 files changed, 51 insertions(+)
New commits:
commit 9d6a3a79eef447420dbad2a0c17bd7dfcbc8f0f0
Author: Keith Packard <keithp at keithp.com>
Date: Sun Dec 8 14:10:42 2024 -0800
test: Add test for correct rounding when reducing float precision
Make sure that reducing float precision rounds to even.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/test/Makefile.am b/test/Makefile.am
index 7748aab..94e9b76 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -11,6 +11,7 @@ check_SCRIPTS=\
hashtest.5c \
signal.5c \
round.5c \
+ fround.5c \
math.5c \
factorial.5c \
is_type.5c \
diff --git a/test/fround.5c b/test/fround.5c
new file mode 100644
index 0000000..efb4a97
--- /dev/null
+++ b/test/fround.5c
@@ -0,0 +1,46 @@
+exception bad_round (int last_bits, int prec, int dist, real computed, rational actual);
+
+void imprecise_check(int last_bits, int prec, int dist)
+{
+ int power = prec - 1;
+ real i = imprecise(1, prec + dist + 100);
+ real f = 0;
+
+ /* add in the last bits */
+ f += last_bits * 2**(-power);
+
+ /* add in a bit just past the value */
+ f += 0.5 * 2**(-power);
+
+ /* Add in a bit far past the value if specified */
+ if (dist > 0)
+ f += 2**(-(power + dist));
+
+ real computed = imprecise(i + f, prec);
+
+ rational actual = 1;
+ bool do_round = false;
+ int last_actual_bits = last_bits;
+
+ if ((last_bits & 1) == 0) {
+ /* If the last bits are even, then round only if the frac is > 0.5 */
+ do_round = dist > 0;
+ } else {
+ /* Otherwise, always round */
+ do_round = true;
+ }
+ if (do_round)
+ last_actual_bits++;
+
+ actual += last_actual_bits * 2 ** (-power);
+
+ if (computed != actual) {
+ printf("computed %a actual %a\n", computed, actual);
+ raise bad_round(last_bits, prec, dist, computed, actual);
+ }
+}
+
+for(int last_bits = 0; last_bits < 8; last_bits++)
+ for(prec = 24; prec <= 57; prec++)
+ for (dist = 0; dist <= 64; dist++)
+ imprecise_check(last_bits, prec, dist);
diff --git a/test/meson.build b/test/meson.build
index 04e32b6..963c4de 100644
--- a/test/meson.build
+++ b/test/meson.build
@@ -17,6 +17,7 @@ tests = [
'hashtest.5c',
'signal.5c',
'round.5c',
+ 'fround.5c',
'math.5c',
'factorial.5c',
'is_type.5c',
commit 8165252d35460a57dafff2ae8b5a3b465bccca34
Author: Keith Packard <keithp at keithp.com>
Date: Sun Dec 8 14:09:21 2024 -0800
float: Check bits in the last chunk during round even
Missed the last few bits of the value when checking for > 0.5
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/float.c b/float.c
index 9752578..4821f99 100644
--- a/float.c
+++ b/float.c
@@ -214,6 +214,9 @@ FpartRound (Fpart *a, int shift)
if (shift < 0) {
last <<= 1;
shift = 0;
+ } else {
+ if (last & ((1 << shift) - 1))
+ round |= 1;
}
round |= (last >> shift) & 3;
}
More information about the Nickle
mailing list