An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
Posted Jul 18, 2015 2:10 UTC (Sat) by Cyberax (✭ supporter ✭, #52523)In reply to: An interview with Larry Wall (LinuxVoice) by raiph
Parent article: An interview with Larry Wall (LinuxVoice)
No. Your 'full precision' actually means "precision loss".
You CAN NOT store 0.1 as a limited binary fraction precisely. You can try to play games like "0.10000000000000009" is really "0.1" but that will inevitably bite some users who actually expect floating point to be precise and it won't be reliable anyway (what we should do with 0.10000000000000010?).
If you need decimal fractions - then use a decimal type.
Posted Jul 18, 2015 6:12 UTC (Sat)
by epa (subscriber, #39769)
[Link] (12 responses)
Posted Jul 22, 2015 17:00 UTC (Wed)
by salimma (subscriber, #34460)
[Link]
Posted Jul 22, 2015 17:53 UTC (Wed)
by anselm (subscriber, #2796)
[Link] (10 responses)
So you would presumably use 22/7 (or something like it) for π?
Posted Jul 22, 2015 18:33 UTC (Wed)
by rsidd (subscriber, #2582)
[Link] (9 responses)
A sensible thing for a language to do, if it must bother with rational numbers without being asked, would be to use a rational representation when the number is explicitly given as a ratio of integers, and the machine floating point representation otherwise. So 1/10 would be rational and 0.1 would be a float, and their product would be coerced to be a float. Lisp, for instance, does this (at least common lisp does). Python on the other hand has a fractions module that must be used if this behaviour is desired, otherwise python 2 treats 1/10 as an int (0) and python 3 treats it as a float (0.1).
Posted Jul 22, 2015 19:49 UTC (Wed)
by raiph (guest, #89283)
[Link]
Posted Jul 23, 2015 3:49 UTC (Thu)
by raiph (guest, #89283)
[Link] (7 responses)
Yes. Pi is irrational, not rational. Any finite representation of an irrational number is going to be approximate, no matter what.
> One has two choices then -- store [0.1] as 1/10 ... or store it in the proper machine representation.
Do you see that you've indulged in circular reasoning there? You've implied that a particular machine storage representation of rational numbers is not proper simply because it isn't floating point. (And, most ironically, you're saying this despite the former being a 100% accurate representation and the latter approximate.)
> Most of us prefer [an inaccurate representation over an accurate one]
I don't think that's true. I think most of us prefer the most appropriate representation for a particular use case if it makes a difference worth making for that use case.
This often means floating point. But, for many uses of rationals, especially decimals, exact rationals are a viable choice, indeed may I say obvious choice, if you care about accuracy and simplicity.
> From raiph's remarks it would seem perl defaults to an integer-ratio for 0.1, and possibly even for π.
Yes, for 0.1.
The π value built in to Perl 6 is stored as a floating point number.
> What puzzles the rest of us is what is the benefit of this.
Almost all practical rational math, eg decimal math where input and output values have any number of digits before the decimal point and up to 15 or so digits after, will be 100% accurate by default, whereas floating point can go wrong at one digit after the decimal point, such as with `0.1 + 0.2 - 0.3`.
So, treating rationals as rationals can provide two crystal clear benefits over floating point: accuracy and simplicity.
> A sensible thing for a language to do ... would be to use a rational representation when the number is explicitly given as a ratio of integers ... So 1/10 would be rational
Right. That's what Perl 6 does and most other languages do not.
> and 0.1 would be a float
0.1 is *exactly* the same number as 1/10. It's just specified with a different notation. Given that Perl 6 supports accurate rational processing it makes little sense to treat `123456789.987654321` as anything other than 123456789987654321/1000000000.
In Perl 6, if you want floating point then you explicitly coerce, eg `Num(0.1)`, or use scientific notation, which is universally understood to be approximate, such as eg `1e-1` for 0.1 or `2.99792458e+8` for the m/s speed of light.
Posted Jul 23, 2015 4:38 UTC (Thu)
by rsidd (subscriber, #2582)
[Link] (6 responses)
Posted Jul 23, 2015 21:59 UTC (Thu)
by flussence (guest, #85566)
[Link]
Why do you hold Perl 6 to an absurd standard here but languages like Javascript, PHP and Python get a silent free pass?
Posted Jul 24, 2015 4:29 UTC (Fri)
by raiph (guest, #89283)
[Link]
Without installing anything you can compile:
say e**(i*π) + 1
... and get an approximation of the right result. (Yes, that i is the square root of -1.)
But I'm pretty sure that's about the maximum extent of it at the moment ie there aren't (m)any other mathematical constants defined in the standard setting.
> > whereas floating point can go wrong at one digit after the decimal point, such as with `0.1 + 0.2 - 0.3`.
> Huh? python (both 2 and 3) give me 5.551115123125783e-17 which is 17 digits after the decimal point, not 1 digit.
I was talking about the user *input* (one decimal digit, presumed accurate) not the computer generated *output*.
> When you have a number with more than two or three digits after the decimal ...
Numbers with just one or two digits after the decimal are considered an important use case. For example, writing 4.10 to represent 4 dollars and 10 cents.
Posted Jul 24, 2015 5:53 UTC (Fri)
by rsidd (subscriber, #2582)
[Link] (3 responses)
Normally (ie when it's some other quantity, not money), when you write 4.10 you mean that it is known to a precision of two digits after the decimal point. If you write 4.1 it means you know it to 1 digit precision. If you mean the exact fraction you will write 4 1/10, not either of the above.
Anyway, enough of this argument. It is clear that you are convinced treating 4.1 or 3.14159 as fractions is the correct thing to do, will not be persuaded that it is wrong, and will not succeed in persuading others that it is right. Let us see if the Perl 6 way catches on. It's only been 15 years so far. Me, I have my eye on Julia.
Posted Jul 24, 2015 9:53 UTC (Fri)
by raiph (guest, #89283)
[Link]
Thanks for the exchange. :)
Posted Jul 26, 2015 15:56 UTC (Sun)
by flussence (guest, #85566)
[Link]
Posted Jul 28, 2015 9:06 UTC (Tue)
by dvdeug (guest, #10998)
[Link]
It's a trade-off of speed for less user surprise, and for a language with as little stress on raw speed as Perl, that's usually a good trade off. Accuracy is probably a wash; I bet there's a lot of times where you get back the exact best answer you could get with rationals where floats are less then precise, especially for less experienced users who aren't thinking in terms of IEEE754. I don't know Perl or Perl 6, but I assume if you want floats, you can explicitly demand them.
Posted Jul 18, 2015 7:49 UTC (Sat)
by Wol (subscriber, #4433)
[Link] (4 responses)
Mind you, it is a pain. The user/programmer has to explicitly manage the exponent ...
Cheers,
Posted Jul 18, 2015 19:05 UTC (Sat)
by raiph (guest, #89283)
[Link] (3 responses)
I'd enjoy comparing the Perl 6 design in this regard with pick's. I didn't find anything helpful when I spent a few minutes searching SO and wikipedia and googling; I'd appreciate a brief elaboration or link.
Perl 6 has a Rational role that is parameterized with a numerator and denominator. FatRats are Rational[Int,Int] which means they are arbitrary precision. Rats are (Rat64s which are) Rational[Int,Uint64] which means the denominator is limited to an unsigned 64 bit int; if a Rat overflows, "the denominator is automatically converted either to a Num or to a lesser-precision Rat, at the discretion of the implementation." (Hmm. Why not to a FatRat?)
The full gory details for this part of the Perl 6 language design (which may or may not exactly match the current Rakudo Perl 6 compiler implementation but ought to be close) are at http://design.perl6.org/S02.html#Numeric_Types
Posted Jul 19, 2015 9:11 UTC (Sun)
by Wol (subscriber, #4433)
[Link] (2 responses)
The Pr1me CPU was capable of doing BCD arithmetic, and had a load of microcode specifically to optimise all this sort of stuff. The Pick database was designed to store integers, and to store the mantissa in the data definition, not the data itself. As an example, let's store some price information in pounds in Pick - you'd put "199" in the data field, and "MD2" in the definition ("masked decimal 2"). That converts data at display time to 2dp, ie 1.99
So when you as the programmer are doing the maths, you have to be wary of multiplying MD-type fields, because MD2 * MD2 is, of course, MD4 and if you don't "correct" it to whatever datatype you're storing the result as, you can get some right funnies ...
Cheers,
Posted Jul 19, 2015 22:43 UTC (Sun)
by raiph (guest, #89283)
[Link] (1 responses)
Gotchya.
Iirc pick doesn't have (much of) a type system and you're describing the kind of problem that type systems address.
I don't see a parallel with anything Perl 6 specific atm.
Thanks for following up. :)
Posted Jul 20, 2015 14:34 UTC (Mon)
by Wol (subscriber, #4433)
[Link]
imho that is both a great strength, and a massive weakness. Everything is a string. Works great (it really does). But the fact that all of your definitions are DEscriptive, rather than PREscriptive, *can* (not *is*) be a nightmare when you really really want to be certain something is, say, a number.
But on the other hand, it does make it easy to store things like "dead" or "unknown" in an age field :-)
Cheers,
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
The π value built in to Perl 6 is stored as a floating point number
Ok, so π is built in -- is every conceivable required irrational also built in? e I would guess, but what about the golden ratio, the Euler-Mascheroni constant, etc etc? What about physical constants like the electronic charge, Planck's constant, etc, which are quantities measured to some accuracy and not exact fractions?
whereas floating point can go wrong at one digit after the decimal point, such as with `0.1 + 0.2 - 0.3`.
Huh? python (both 2 and 3) give me 5.551115123125783e-17 which is 17 digits after the decimal point, not 1 digit. Who exactly cares about this? If you were building a football stadium and your calculation gave you this sort of error, you would be wrong by one-hundredth the radius of an atomic nucleus.
Given that Perl 6 supports accurate rational processing it makes little sense to treat `123456789.987654321` as anything other than 123456789987654321/1000000000.
This is exactly where we disagree. You think treating 123456789.987654321 as a fraction is reasonable and even desirable. I think it is ridiculous. When you have a number with more than two or three digits after the decimal, it is almost certainly an inexact value -- a roundoff, or a measurement, or just a ballpark figure. There is absolutely no reason to treat it as a fraction. It hurts performance and does not improve accuracy. And when people want the fraction 1/10, they will write 1/10, not 0.1. Out of curiosity, were there any mathematical/scientific programmers behind these Perl 6 decisions?
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
Why do you hold Perl 6 to an absurd standard here but languages like Javascript, PHP and Python get a silent free pass?
I guess I wasn't clear enough. You said pi is a float because it's built-in and you know it is irrational, but if you write 3.14159265 it will be treated as the fraction 314159265/100000000. So I was asking what about other constants? If I write phi=1.61803398 why should perl assume that I have a fraction in mind? If I wanted a fraction I'd write a fraction. Other languages don't have this problem, you can define what constants you like and they will be treated as floats without coercion. In Perl 6, even you managed to get the coercion wrong here.
Numbers with just one or two digits after the decimal are considered an important use case. For example, writing 4.10 to represent 4 dollars and 10 cents.
This is a special case. For 4 dollars 10 cents, you will write 4.10, not 4.1 or 4.100. Changing how floats are treated in the language because of this special case is just weird. Counting in cents, as integers, is the sensible thing to do. But if you want smaller units than one cent (eg compound interest calculations), you want floats, not fractions.
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
Wol
An interview with Larry Wall (LinuxVoice)
An interview with Larry Wall (LinuxVoice)
Wol
An interview with Larry Wall (LinuxVoice)
> you have to be wary of multiplying [such] fields
An interview with Larry Wall (LinuxVoice)
Wol