4 ms·
Unless they're using an alternate exact representation for floats by default, that's just rounding them when printing.
by reitzensteinm 7y ago
Unless they're using an alternate exact representation for floats by default, that's just rounding them when printing.
- yellowapple 7y agoThat'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/ 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).
- dnautics 7y agoIt depends. Do you want deterministic compute time? Then you have to settle for something inaccurate.
- reitzensteinm 7y agoI am aware of numeric towers and actually checked whether that was going on. sbcl 1.4.16 uses single floats: https://ideone.com/ruw5qi https://ideone.com/ruw5qi I don't know enough about Scheme to dig under the covers to see how it's being represented internally.
- verandacoffee 7y agosbcl (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.
- sjamaan 7y agoScheme 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
- yellowapple 7y agoPer 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.
- fiddlerwoaroof 7y agoYeah, 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.
- yellowapple 7y ago> 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 :)
- reitzensteinm 7y agoThis 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.
- yellowapple 7y agonorthrup@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.