Re: Bug in srfi-48?
Shiro Kawai <[email protected]> Fri, 13 Oct 2017 09:54:51 -1000
| Newsgroups | gmane.lisp.scheme.srfi.srfi-48 |
|---|---|
| Message-ID | <CALN0JNHuA1aYUcHUVQmn5owGZ4v8K=MLADbWVmb9sMyB1z3iTA@mail.gmail.com> |
--001a1134f460b3d4f0055b730702 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-SL-Modified: truncated_text "Scale by 10^d and round" scheme works mostly, and I use it often when the rare case doesn't matter. I vaguely remember there're fail cases due to double rounding (scaling by 10^d requires more bits than the original number, causing the spilled bits to be rounded by floating-point calculation, and in rare cases, that rounding crosses over the midpoint of our rounding). I couldn't find the actual case now, though. On Fri, Oct 13, 2017 at 7:52 AM, Donald Allen <[email protected]> wrote: > On 13 October 2017 at 13:51, Marc Feeley <[email protected]> wrote: > > I=E2=80=99ve found this code works well for me=E2=80=A6 > > > > (define (num->string num w d) ; w =3D total width, d =3D decimals > > (let ((n (round (* (abs (inexact->exact num)) (expt 10 d))))) > > (let ((i (quotient n (expt 10 d))) > > (f (modulo n (expt 10 d)))) > > (let ((si (string-append > > (if (< num 0) "-" "") > > (number->string i 10))) > > (sf (if (> d 0) > > (let ((sf (number->string (+ f (expt 10 d)) 10))) > > (string-set! sf 0 #\.) > > sf) > > ""))) > > (let ((lsi (string-length si)) > > (lsf (string-length sf))) > > (let ((blanks (- w (+ lsi lsf)))) > > (string-append (make-string (max blanks 0) #\space) si > sf))))))) > > > > Perhaps that=E2=80=99s better for your purpose than srfi-48. > > Thank you. I will give it a try. > > /Don > --001a1134f460b3d4f0055b730702 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-SL-Modified: truncated_html <div dir=3D"ltr">"Scale by 10^d and round" scheme works mostly, a= nd I use it often when the rare case doesn't matter.<div>I vaguely reme= mber there're fail cases due to double rounding (scaling by 10^d requir= es more bits than</div><div>the original number, causing the spilled bits t= o be rounded by floating-point calculation, and in rare cases,</div><div>th= at rounding crosses over the midpoint of our rounding).=C2=A0 =C2=A0I could= n't find the actual case now, though.</div><div><br></div></div><div cl= ass=3D"gmail_extra"><br><div class=3D"gmail_quote">On Fri, Oct 13, 2017 at = 7:52 AM, Donald Allen <span dir=3D"ltr"><<a href=3D"mailto:donaldcallen@= gmail.com" target=3D"_blank">[email protected]</a>></span> wrote:<b= r><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:= 1px #ccc solid;padding-left:1ex"><span class=3D"">On 13 October 2017 at 13:= 51, Marc Feeley <<a href=3D"mailto:[email protected]">[email protected]= montreal.ca</a>> wrote:<br> > I=E2=80=99ve found this code works well for me=E2=80=A6<br> ><br> > (define (num->string num w d) ; w =3D total width, d =3D decimals<b= r> >=C2=A0 (let ((n (round (* (abs (inexact->exact num)) (expt 10 d)))))= <br> >=C2=A0 =C2=A0 (let ((i (quotient n (expt 10 d)))<br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (f (modulo n (expt 10 d))))<br> >=C2=A0 =C2=A0 =C2=A0 (let ((si (string-append<br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (if (<= ; num 0) "-" "")<br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (number-= >string i 10)))<br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (sf (if (> d 0)<br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (= let ((sf (number->string (+ f (expt 10 d)) 10)))<br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 (string-set! sf 0 #\.)<br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 sf)<br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &= quot;")))<br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 (let ((lsi (string-length si))<br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (lsf (string-length sf= )))<br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (let ((blanks (- w (+ lsi lsf))))<br> >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (string-append (make-string (= max blanks 0) #\space) si sf)))))))<br> ><br> > Perhaps that=E2=80=99s better for your purpose than srfi-48.<br> <br> </span>Thank you. I will give it a try.<br> <br> /Don<br> </blockquote></div><br></div> --001a1134f460b3d4f0055b730702--