5 ms·
Why is this surprising? Floats are defined by the hardware essentially, not the language. And this is how they work: they're binary, not decimal. Computers a
by chubot 11y ago
Why is this surprising? Floats are defined by the hardware essentially, not the language.
And this is how they work: they're binary, not decimal. Computers are binary, not decimal. 0.1 can't be represented exactly as binary.
Python has a decimal type, if that's what you want: https://docs.python.org/2/library/decimal.html https://docs.python.org/2/library/decimal.html
I consider it a basic point of computer literacy to understand this.
- _pmf_ 11y ago> I consider it a basic point of computer literacy to understand this. Yes, but just because fractional notation defaults to a floating point representation in most languages does not mean that the option of defaulting to decimal/rational notation at the language level should be ruled out generally.
- raiph 11y ago> Floats are defined by the hardware essentially, not the language. Floats are storage formats for approximations of numbers. Floats are, by definition, not relevant if one wants to store an exact number exactly. > 0.1 can't be represented exactly as binary. 1 can be represented exactly as binary. And so can 10. And thus 1 (numerator) divided by 10 (denominator) can be represented by two (binary -- or any-other-ary-for-that-matter) numbers. This isn't about (just) decimals. The same thing applies to non-decimal fractions like 1/3 or 56,123 / 7329. Some languages prefer to store exact representations of rational numbers. Perl 6 is by no means the first.
- haberman 11y ago> Floats are storage formats for approximations of numbers. Floats are, by definition, not relevant if one wants to store an exact number exactly. Floats can store integer values exactly up to an upper limit (2^24 IIRC), which is often useful. And they can store binary fractions exactly up to a point. No number representation can represent all numbers exactly. Each can store some subset of all numbers exactly.
- raiph 11y agoFwiw I can't tell if you're being pedantic for fun or not. I'm going to stick with fun... > Floats can store integer values exactly up to an upper limit (2^24 IIRC) You're right, for relatively small integers of 8 digits or so. Here's a fun place to note that on the machine I just tried the Rakudo Perl 6 compiler will happily exactly store integers with hundreds of thousands of digits. > which is often useful. As in you've written such code in dozens of programs? > And [floats] can store binary fractions exactly up to a point. 0.1 is already "past" that point which is even less impressive than 8 digit integers. > No number representation can represent all numbers exactly. Each can store some subset of all numbers exactly. Well duh. No computer can compute all computable things. Each can compute some things. My machine became unhappy when I asked it to store a number that would require a terabyte of RAM. Are these sorts of thing really worth mentioning when the starting point is just 0.1 + 0.2 == 0.3?
- jjnoakes 11y agoFloating point hardware storing integers is useful indeed. Look up JavaScript. A language storing big numbers in non-native formats, like your Rakudo example, is irrelevant to the parent's point. 0.1 isn't past any "point" (whatever that means). It just isn't representable without recurrence in base 2 much like 1/3 isn't in base 10. Your post could do without 'duh' and the like as well.
- raiph 11y ago> A language storing big numbers in non-native formats, like your Rakudo example, is irrelevant to the parent's point. I thought being able to store an up to 8 digit integer in a float was an interesting tidbit. I already knew it but others might not. However, it was also completely irrelevant to a discussion of why 0.1 + 0.2 equals 0.3 in Perl 6 and, imo, even to my (slight over) emphasis that a float is for (efficient) storage and processing of approximations, not exact numbers. > 0.1 isn't past any "point" (whatever that means). Precisely. I was directly responding to "And [floats] can store binary fractions exactly up to a point." What does that mean? "up to a point" is highly ambiguous. The fact that 0.1 isn't stored exactly is completely unambiguous. > It just isn't representable without recurrence in base 2 much like 1/3 isn't in base 10. So what? It is representable without recurrence in a pair of base 2 numbers, eg 1 (numerator) and 11 (denominator) for 1/3. > Your post could do without 'duh' OK. I considered that and thought it was OK, all things considered, given that it wasn't prominent and succinctly expressed my reaction. But I hear you that even such a gentle 'duh' is problematic and will be even more careful about how I express myself at HN in future. > and the like as well. Would you be willing to be specific? While I recognize the 'duh' is edgy, I've reread the rest of what I wrote and don't understand what you think I got wrong.
- themodelplumber 11y ago> I consider it a basic point of computer literacy to understand this. Which statement does, by itself, a pretty good job of explaining why nobody even bothers to ask themselves if they are computer literate these days.
- kbenson 11y agoWhile defaulting to floats for rational numbers may be the default for many languages, it is by no means the only way to store them, which is why we're talking about them. In Perl 6 they are often stored as a numerator and denominator within the Rat type, and converted for display.
- cicero 11y agoFor example... Welcome to DrRacket, version 6.2 [3m]. Language: racket; memory limit: 128 MB. > (= (+ 0.1 0.2) 0.3) #f > (= (+ 1/10 2/10) 3/10) #t
- schoen 11y agoHow come a LISP allows you to write 1/10 instead of (/ 1 10)? Is it a special case for entering fractions, or does Racket allow arbitrary arithmetic expressions with infix operators?
- soegaard 11y ago1/10 is a literal. It denotes the value one tenth. The expression (/ 1 10) will at runtime calculate 1 divided by 10. Most programming languages have syntax for writing all available numbers as literals. Racket do not have builtin syntax for infix arithmetic - but there are various packages available for infix expressions.
- raiph 11y agoDo you know if there was ever any public discussion about whether to represent decimal fractions (0.1 etc.) as an exact rational or inexact float?
- soegaard 11y agoTake a look that the rrrs mailing list archive.
- 11y ago
- dragonwriter 11y agoThat decimal literals represent binary floating point numbers is defined by the language, not the hardware. I consider it a basic point of language design literacy that exact decimal literals without some other indicators should not represent an inexact type that isn't designed to represent decimal data. Infuriatingly, very few languages get that right. But perl 6 isn't unique in doing so; Scheme had been doing it right for decades.
- dragonwriter 11y ago(Actually, Scheme doesn't quite get this right: decimals are inexact by default and only rationals expressed as divisions of integers are exact, though it is less cumbersome to specify an exact decimal than in most popular language -- its a literal modifier, not a function call.) e.g.: 0.2 is inexact, while #e0.2 is exact.
- raiph 11y agoThe use of an annotative '#e' to get an exact number contrasts with Perl 6's choices for the default interpretation of number literals. The Perl 6 choice adopts scientific notation to correspond to floats: 200000000000000000000 # exact (integer) 2 * 10 ** 20 0.00000000000000000002 # exact (rational) 2 * 10 ** -20 0.2e-19 # inexact (float) 2 * 10 ** -20 2e20 # inexact (float) 2 * 10 ** 20
- kamaal 11y ago>>Why is this surprising? Because it goes against intuition? The whole point of a higher level language is an abstraction over these kind of problems anyway.
- natch 11y agoLike I said, cue the sophomoric replies about IEEE floating point number representation.