0.1 + 0.2 → 0.30000000000000004 0.1 + 0.2 → 0.30000000000000004 $ irb
irb(main):001:0> 0.1 + 0.2
=> 0.30000000000000004
irb(main):002:0>
$ iex
Erlang/OTP 22 [erts-10.6.2] [source] [64-bit] [smp:16:16] [ds:16:16:10] [async-threads:1] [hipe]
Interactive Elixir (1.10.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 0.1 + 0.2
0.30000000000000004
iex(2)>
$ python
Python 2.7.17 (default, Dec 2 2019, 13:23:33)
[GCC 4.2.1 Compatible Apple LLVM 11.0.0 (clang-1100.0.33.12)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 0.1 + 0.2
0.30000000000000004
>>> northrup@Topaz:~/Desktop$ perl -de1
Loading DB routines from perl5db.pl version 1.55
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(-e:1): 1
DB<1> say 0.1 + 0.2
0.3
[…] northrup@Topaz:~$ csi
CHICKEN
(c) 2008-2019, The CHICKEN Team
(c) 2000-2007, Felix L. Winkelmann
Version 5.1.0 (rev 8e62f718)
linux-unix-gnu-x86-64 [ 64bit dload ptables ]
#;1> (+ 0.1 0.2)
0.3
[…] 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.3There 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).
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.
(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.
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.10000000000000001Aside from financial applications, there’s very little reason to care about the trailing remainder.
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 :)
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 DB<1> say((0.1+0.2) != 0.3)
1