Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

That's a fair point about the Perl example, but Scheme and Common Lisp (including both Chicken and SBCL, last I checked) support (if not outright require) full numeric towers with rational number types, so these are indeed exact representations (unless you explicitly request binary floats for e.g. performance reasons) and not just rounding during printing.

There are lots of other examples of doing it "right" (using more suitable numeric types) over at https://0.30000000000000004.com/ (alongside a bunch of examples that, to your point, just round, or to the GP's point, just stick to binary floats).



Yeah, in CL the 0.1 is read syntax for a float (IEEE-754ish on most modern implementations.) If you want exactly 0.1, you’d have to say 1/10. The printer is probably cheating and rounding to the output you expect (I think Python 3 may do this now?)

Aside from financial applications, there’s very little reason to care about the trailing remainder.


> The printer is probably cheating and rounding to the output you expect

    northrup@Topaz:~$ sbcl
    This is SBCL 1.5.8, an implementation of ANSI Common Lisp.
    More information about SBCL is available at <http://www.sbcl.org/>.
    
    SBCL is free software, provided as is, with absolutely no warranty.
    It is mostly in the public domain; some portions are provided under
    BSD-style licenses.  See the CREDITS and COPYING files in the
    distribution for more information.
    * (= (+ 0.1 0.2) 0.3)
    T
    * (= (- (+ 0.1 0.2) 0.3) 0)
    T
> Aside from financial applications

"Financial applications" happen to be pretty common reasons for number crunching :)


This just means that 0.3 has the same internal representation as the result of (0.1 + 0.2).

Internally, they're probably both 0.30000000000000004 (depending on precision), so an equality check returns true.

It could also be that they're both 3/10 rational numbers, but given other tests in this thread that's likely not the case out the box.


    northrup@Topaz:~$ sbcl
    This is SBCL 1.5.8, an implementation of ANSI Common Lisp.
    More information about SBCL is available at <http://www.sbcl.org/>.
    
    SBCL is free software, provided as is, with absolutely no warranty.
    It is mostly in the public domain; some portions are provided under
    BSD-style licenses.  See the CREDITS and COPYING files in the
    distribution for more information.
    * (- 0.3 3/10)
    0.0
    * (= (- 0.3 3/10) 0)
    T
    * (= (- 3/10 0.3) 0)
    T
    * (= 0.3 3/10)
    NIL
So yeah, 0.3 and 3/10 are definitely distinct, but still apparently net out to exactly 0 nonetheless.


    CL-USER(3): (rational (+ 0.1 0.2))
    
    5033165/16777216
    CL-USER(3): (rational 0.3)
    
    5033165/16777216


I am aware of numeric towers and actually checked whether that was going on.

sbcl 1.4.16 uses single floats: https://ideone.com/ruw5qi

I don't know enough about Scheme to dig under the covers to see how it's being represented internally.


Scheme is the same. If you type a number with a dot in it, you'll get an "inexact" number, which is floating point. If you prefix it with #e, you'll get an exact representation of the entered number (so, e.g. #e0.1 gives you 1/10)

The output of inexact numbers is typically truncated. In CHICKEN, you can use flonum-print-precision to tweak that. In an example, straight from the manual:

    > (flonum-print-precision 17)
    > 0.1
    0.10000000000000001


sbcl (and other Common Lisps) uses what you want it to use: read-default-float-format

(setf read-default-float-format 'single-float) (+ 0.1 0.2) => 0.3

(setf read-default-float-format 'double-float) (+ 0.1 0.2) => 0.30000000000000004

On LispWorks 7.0 I get 0.30000000000000005 for double-float. Hmm.


Per my other comment, SBCL's defaults still cause (= (- (+ 0.1 0.2) 0.3) 0) → T. I guess they're technically floats (or at the very least not rationals) given that (= 0.3 3/10) → NIL.


It depends. Do you want deterministic compute time? Then you have to settle for something inaccurate.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: