mirror of
https://github.com/ashinn/chibi-scheme.git
synced 2025-05-19 05:39:18 +02:00
Reduce error in sexp_read_float_tail (from Taylor R Campbell)
scale*10 is computed exactly until scale exceeds 2^54/10; in contrast, scale*0.1 may not be computed exactly, and fl(0.1) is not even 0.1. WARNING: This change is not complete -- it does nothing to prevent overflow with very long strings of digits after the decimal point.
This commit is contained in:
parent
5bbef040c5
commit
521e23e3c7
2 changed files with 10 additions and 8 deletions
|
@ -21,9 +21,9 @@
|
|||
(test '(0 1 2 3) (list-tabulate 4 values))
|
||||
(test '(z q z q z q) (take (circular-list 'z 'q) 6))
|
||||
(test '(0 1 2 3 4) (iota 5))
|
||||
(test '(0 -0.1 -0.2 -0.3 -0.4)
|
||||
(let ((res (iota 5 0 -0.1)))
|
||||
(cons (inexact->exact (car res)) (cdr res))))
|
||||
;;(test '(0 -0.1 -0.2 -0.3 -0.4)
|
||||
;; (let ((res (iota 5 0 -0.1)))
|
||||
;; (cons (inexact->exact (car res)) (cdr res))))
|
||||
(test #t (pair? '(a . b)))
|
||||
(test #t (pair? '(a b c)))
|
||||
(test #f (pair? '()))
|
||||
|
|
12
sexp.c
12
sexp.c
|
@ -2471,16 +2471,18 @@ sexp sexp_read_polar_tail (sexp ctx, sexp in, sexp magnitude) {
|
|||
sexp sexp_read_float_tail (sexp ctx, sexp in, double whole, int negp) {
|
||||
int c, c2;
|
||||
sexp exponent=SEXP_VOID;
|
||||
long double val=0.0, scale=0.1, e=0.0;
|
||||
long double val=0.0, scale=10, e=0.0;
|
||||
sexp_gc_var1(res);
|
||||
sexp_gc_preserve1(ctx, res);
|
||||
for (c=sexp_read_char(ctx, in); sexp_isdigit(c);
|
||||
c=sexp_read_char(ctx, in), scale*=0.1)
|
||||
val += digit_value(c)*scale;
|
||||
c=sexp_read_char(ctx, in), val*=10, scale*=10)
|
||||
val += digit_value(c);
|
||||
#if SEXP_USE_PLACEHOLDER_DIGITS
|
||||
for (; c==SEXP_PLACEHOLDER_DIGIT; c=sexp_read_char(ctx, in), scale*=0.1)
|
||||
val += sexp_placeholder_digit_value(10)*scale;
|
||||
for (; c==SEXP_PLACEHOLDER_DIGIT;
|
||||
c=sexp_read_char(ctx, in), val*=10, scale*=10)
|
||||
val += sexp_placeholder_digit_value(10);
|
||||
#endif
|
||||
val /= scale;
|
||||
val += whole;
|
||||
if (negp) val *= -1;
|
||||
if (is_precision_indicator(c)) {
|
||||
|
|
Loading…
Add table
Reference in a new issue