Hi all, This is a patch and bugreport rolled into one ;)
While testing the "numbers" egg I found out that programs containing flonum literals can behave differently when compiled or interpreted. This turns out to be caused by the fact that Chicken just uses [sf]printf or gcvt to print flonums while emitting C code. When nothing else is specified, these use the default "flonum-print-precision" of 15, which means that any number with more _decimal_ digits than that get printed in exponential notation, like this: #;1> 123456789012345.0 123456789012345.0 #;2> 1234567890123456.0 1.23456789012346e+15 So after (read)ing the literal the compiler then later prints it back again, but with less precision than was present when reading it. This behavior can be tweaked by calling (flonum-print-precision N), which is exactly what the compiler should be doing and what my patch does. You can also merge it from the "sjamaan-pending" branch, it's changeset 6c39851e1504d01b2de05e014f5542913e3e5c5e. PS: If someone with access to a Windows system is reading this, there's a sort-of related bug in #691. I've attached a patch that needs to be tested to the ticket. Cheers, Peter -- http://sjamaan.ath.cx -- "The process of preparing programs for a digital computer is especially attractive, not only because it can be economically and scientifically rewarding, but also because it can be an aesthetic experience much like composing poetry or music." -- Donald Knuth
>From 6c39851e1504d01b2de05e014f5542913e3e5c5e Mon Sep 17 00:00:00 2001 From: Peter Bex <peter....@xs4all.nl> Date: Sat, 17 Sep 2011 17:41:58 +0200 Subject: [PATCH] Do not drop precision in flonums when compiling --- c-backend.scm | 2 ++ tests/compiler-tests.scm | 13 +++++++++++++ 2 files changed, 15 insertions(+), 0 deletions(-) diff --git a/c-backend.scm b/c-backend.scm index 1571edb..5dbcadd 100644 --- a/c-backend.scm +++ b/c-backend.scm @@ -60,6 +60,8 @@ ;;; Generate target code: (define (generate-code literals lliterals lambdas out source-file dynamic db) + ;; Don't truncate floating-point precision! + (flonum-print-precision (+ flonum-maximum-decimal-exponent 1)) (let () ;; Some helper procedures diff --git a/tests/compiler-tests.scm b/tests/compiler-tests.scm index 7395130..226c440 100644 --- a/tests/compiler-tests.scm +++ b/tests/compiler-tests.scm @@ -216,3 +216,16 @@ (assert (zero? b)))) (gp-test) + +;; Test that encode-literal doesn't drop digits for extreme flonum values. + +;; This number is 2^971 * (2^53 - 1), and is the positive "all ones" number for +;; 64-bit flonums with precision 53 and significand/mantissa 10. +;; If we want to support 32-bit flonums or flonums with different precision +;; or significand, we need a cond-expand here or something. +;; Technically, even larger decimal numbers can be represented by flonums. +;; This number can correctly be compared exactly. +(assert (= (* (- (expt 2 flonum-precision) 1) + (expt 2 (- flonum-maximum-exponent flonum-precision))) + 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0 + (string->number "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0"))) \ No newline at end of file -- 1.7.3.4
_______________________________________________ Chicken-hackers mailing list Chicken-hackers@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-hackers