One of the many reasons I think we all would've been better off, had Brendan Eich decided he'd been able to simply use Scheme within the crazy time constraint he'd been given, rather than create JavaScript, :) is that Scheme comes with a distinction between exact and inexact numbers, in its numerical tower: https://en.wikipedia.org/wiki/Numerical_tower One change I'd consider making to Scheme, and to most high-level…
This would make particular sense in a language like python, which no one (should?) be using for systems programming.
0.1 and 0.2 Returns 0.30000000000000004 (2018)
101–110 of 161 posts
Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)
#102Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)
#103Indeed, and therefore: 0.1 + 0.2 != 0.3 You can check it in the JavaScript console. This actually makes me wonder if anyone's ever attempted a floating-point representation that builds in an error range , and correctly propagated/amplified error over operations. E.g. a simple operation like "1 / 10" (to generate 0.1) would be stored not as a single floating-point value, but really as the range between the closest rep…
The flip side is that you generate plenty of false positives once your error ranges get large enough. This happens pretty readily if you e.g. perform iterations that are supposed to keep the numbers at roughly the same scale.
Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)
#104Earlier quoted context omitted.
> Please, tell me, mister, how would you perform complex numerical calculations efficiently? If your calculation turned out to be incorrect it doesn't matter if it's efficient. Correct FP calculation requires error analysis, which is a concrete definition of "how to use it". If you mostly use packaged routines like LAPACK, then you don't exactly need FP; you need routines that internally use FP.
> Correct FP calculation requires error analysis No, it does not. Please, don't make it seem harder than it needs to. 99% applications, if you don't do anything stupid you are completely fine. If you care for precision so much the last digit make difference for you you are probably one of very few cases. I remember somebody giving an example circumference of solar system showing uncertainty of the value of Pi availab…
In this case, "doing anything stupid" includes equality checks. This is the sort of footgun that a huge number of people are going to run into.
Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)
#105One of the many reasons I think we all would've been better off, had Brendan Eich decided he'd been able to simply use Scheme within the crazy time constraint he'd been given, rather than create JavaScript, :) is that Scheme comes with a distinction between exact and inexact numbers, in its numerical tower: https://en.wikipedia.org/wiki/Numerical_tower One change I'd consider making to Scheme, and to most high-level…
A Scheme system that implemented exact reals as unnormalized floating decimal (IEEE 754-2008), coupled with a directive that said `numbers with a decimal point should/should not be read as exact' would be wonderful, not just for financial things, but also for teaching students.
As an example of a Scheme-ish `#lang`, here's a Racket `#lang sicp` that I made to mimic MIT Scheme, as well as add a few things needed for SICP: https://github.com/sicp-lang/sicp/blob/master/sicp/main.rkt
It would be even easier to make a `#lang better-scheme`, by defining just a few changes relative to `racket-base`, such as how numbers are read.
Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)
#106The focus should be on _rational_ numbers. This particular example is all about representation error - precision is implicated, but not the cause.
Ignore precision for a second: The inputs 0.1 and 0.2 are intended to be _rational_. This means they can be accurately represented finitely (unlike an irrational number like PI). Now when using fractions they can _always_ be accurately represented finitely in any base:
1/10=
base 10: 1/10
base 2: 1/1010
2/10=
base 10: 2/10
base 2: 10/1010
The neat thing about rationals, is that when using the four basic arithmetic operations: two rational inputs will always produce one rational output :) this is relevant: 1/10 and 2/10 are both rationals, there is no fundamental reason that addition cannot produce 3/10. When using a format that has no representation error (i.e fractions) the output will be rational for all rational inputs (given enough precision, which is not a realistic issue in this case). When we add these particular numbers in our heads however, almost everyone uses decimals (base 10 floating point), and in this particular case that doesn't cause a problem, but what about 1/3?This is the key: rationals cannot always be represented finitely in floating point formats, but this is merely an artifact of the format and the base. Different bases have different capabilities:
1/10=
base 10: 0.1
base 2: 0.00011001100110011r
2/10=
base 10: 0.2
base 2: 0.00110011001100110r
1/3=
base 10: 0.33333333333333333r
base 2: 0.01010101010101010r
IEEE754 format is a bit more complicated than above, but this is sufficient to make the point.If you can grok that key point (representation error), here's the real understanding of this problem:
Deception 1: The parser has to convert '0.1' decimal into base 2, which will cause the periodic significand '1001100110011' (not accurately stored at any precision)... yet when you ask for it back, the formater magically converts it to '0.1' why? because the parser and formater have symmetrical error :) This is kinda deceptive, because it makes it look like storage is accurate if you don't know what's going on under the hood.
Deception 2: Many combinations of arithmetic on simple rational decimal inputs also have rational outputs from the formatter, which furthers the illusion. For example, nether 0.1 or 0.3 are representable in base 2, yet 0.1 + 0.3 will be formatted to '0.4' why? It just happens that the arithmetic on those inaccurate representations added up to the same error that the parser produces when parsing '0.4', and since the parser and formatter produce symmetric error, the output is a rational decimal.
Deception 3: Most of us grew up with calculators, or even software calculator programs. All of these usually round display values to 10 significant decimals by default, which is quite a bit less than the max decimal output of a double. This always conceals any small representation errors output by the formatter after arithmetic on rational decimal inputs - which makes calculators look infallible when doing simple math.
Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)
#107Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)
#108Floating point considered harmful Edit: this is not a blanket statement. It was meant in the context.
"People repeating stuff without understanding it considered harmful." Floating point is extremely useful. Too bad so many people have no idea how and when to use it. Including some people that design programming languages. Please, tell me, mister, how would you perform complex numerical calculations efficiently? I guess we should just forget about drones and bunch other stuff because 90% of developers have no clue ho…
var n = get_n() // valid to .5g
n = transform(n)
...
// 5 carried over here
You can’t even infer the precision from a FP number alone, especially if it is close to log10(53). /editIn a proper-numbers lang, if someone needed FP numbers, they could just 0.1f. Otherwise 0.1 would mean just that, and counting by 0.1+rand(100) from 1000000 to 0 would not make you scratch your head at the end of the loop and worry whether the rest is just a FP error or an algorithmic error which must be fixed.
90% of developers who know how to use FP still hate it in non-FP tasks, because there is no 0.1nobs literal, how about that.
Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)
#109In R, there are functions for practical equality (to within a tolerance that makes sense on the local machine), e.g. > all.equal(0.1+0.2,0.3) [1] TRUE and functions for actual equality, e.g. > identical(0.1+0.2,0.3) [1] FALSE
Re: 0.1 and 0.2 Returns 0.30000000000000004 (2018)
#110http://pages.cs.wisc.edu/~david/courses/cs552/S12/handouts/g...