I think this is caused by format-scale-exponent. I think it divides 46d7 by 1d8 (or 1d9?) That causes a round-off error which shows up in the printed answer.
The only solution I know of is not to do that scaling and to use a different printing algorithm.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Cmucl and sbcl both use Burger and Dybvig's printing algorithm for the core printing routine. But that's not enough. AFAIK, you need to get rid of the scaling part altogether. CMUCL does that. Don't know about sbcl.
There are lots of hairy little corners to handle.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
the following patch appears to fix the problem:
--- format.lisp.~1.48.~ 2006-12-27 18:01:58.000000000 -0500
+++ format.lisp 2008-03-28 17:31:36.002851000 -0400
@@ -712,7 +712,7 @@
(declare (ignore significand))
(if (zerop arg)
(values zero 0)
- (let* ((expon10a (truncate (* expon lg2))) ; round is not used, in order to avoid overflow
+ (let* ((expon10a (round (* expon lg2)))
(signif10a (/ arg (expt ten expon10a))))
(do ((ten-power ten (* ten-power ten))
(signif10b signif10a (/ signif10a ten-power))
it breaks printing large numbers though, e.g.,
> (format nil "~ve" 31 most-positive-short-float)
*** - /: floating point overflow
which should be fixed by rewriting is in C and increasing the precision.
are there any other pitfalls here?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
As far as I can tell, format-scale-exponent-aux still returns arg/10^n. There will be a round off error such that arg/10^n won't have the same digits as arg in some cases. The only way I could think of to solve this was to compute n, but don't do the division. Then the main print routine prints arg correctly with just the desired digits, but no exponent. Since you know the exponent n already, you can just print that out.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
thank you for your bug report.
the bug has been fixed in the CVS tree.
you can either wait for the next release (recommended)
or check out the current CVS tree (see http://clisp.cons.org\)
and build CLISP from the sources (be advised that between
releases the CVS tree is very unstable and may not even build
on your platform).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Logged In: YES
user_id=28849
Originator: NO
I think this is caused by format-scale-exponent. I think it divides 46d7 by 1d8 (or 1d9?) That causes a round-off error which shows up in the printed answer.
The only solution I know of is not to do that scaling and to use a different printing algorithm.
Logged In: YES
user_id=5735
Originator: NO
increasing precision can result in
> (> (format nil "~ve" 26 46d7)
" 4.5999999999999999998d+8"
> (= 4.5999999999999999998d+8 46d7)
T
which is no longer a bug technically but still worse than sbcl's
" 4.6d+8"
do you know what they do?
Logged In: YES
user_id=28849
Originator: NO
Cmucl and sbcl both use Burger and Dybvig's printing algorithm for the core printing routine. But that's not enough. AFAIK, you need to get rid of the scaling part altogether. CMUCL does that. Don't know about sbcl.
There are lots of hairy little corners to handle.
Logged In: YES
user_id=5735
Originator: NO
the following patch appears to fix the problem:
--- format.lisp.~1.48.~ 2006-12-27 18:01:58.000000000 -0500
+++ format.lisp 2008-03-28 17:31:36.002851000 -0400
@@ -712,7 +712,7 @@
(declare (ignore significand))
(if (zerop arg)
(values zero 0)
- (let* ((expon10a (truncate (* expon lg2))) ; round is not used, in order to avoid overflow
+ (let* ((expon10a (round (* expon lg2)))
(signif10a (/ arg (expt ten expon10a))))
(do ((ten-power ten (* ten-power ten))
(signif10b signif10a (/ signif10a ten-power))
it breaks printing large numbers though, e.g.,
> (format nil "~ve" 31 most-positive-short-float)
*** - /: floating point overflow
which should be fixed by rewriting is in C and increasing the precision.
are there any other pitfalls here?
Logged In: YES
user_id=28849
Originator: NO
As far as I can tell, format-scale-exponent-aux still returns arg/10^n. There will be a round off error such that arg/10^n won't have the same digits as arg in some cases. The only way I could think of to solve this was to compute n, but don't do the division. Then the main print routine prints arg correctly with just the desired digits, but no exponent. Since you know the exponent n already, you can just print that out.
Logged In: YES
user_id=5735
Originator: NO
* lisparit.d (FLOAT-SCALE-EXPONENT): implement
* constsym.d, subr.f (float_scale_exponent): declare
* format.lisp (format-scale-exponent-aux, format-scale-exponent): remove
(format-float-for-e, format-general-float): use
FLOAT-SCALE-EXPONENT instead of FORMAT-SCALE-EXPONENT
Logged In: YES
user_id=5735
Originator: NO
thank you for your bug report.
the bug has been fixed in the CVS tree.
you can either wait for the next release (recommended)
or check out the current CVS tree (see http://clisp.cons.org\)
and build CLISP from the sources (be advised that between
releases the CVS tree is very unstable and may not even build
on your platform).