On Wed, 26 Feb 2020, Todd Chester via perl6-users wrote: > Hi Tobias, > > I am confused as to as to what you mean by numerator and > denominator. >
Rational numbers can always be written as the ratio of two integers: a/b with b non-zero. One calls a the numerator and b the denominator. In Raku the types Int, Rat, FatRat and Num are all rational numbers, as they all can be written as the ratio of two integers (up to Infs and NaNs). > When I say: > $ p6 'say (99/70).base-repeating();' > (1.4 142857) > > $ p6 'say (665857/470832).base-repeating();' > (1.4142 > 135623746899106262955788901349101165596221157440445849050192000543718353892683589900431576443402317599483467563801950589594590002378767798280490705814388146939885139497740170591633533829476331260407109117477146837937948142861997485302613246338396710503958949264281102388962517415978523125021238998198932952730485608454820403031229822951711013694906038671967920617120331668195874536989839263261630475413735684915213919189859652699901451048356951099330546776769633329935093621504060896455635980562068848336561661059571142148367145818466034594080266421993407414959051211472457267) > > $ p6 'say sqrt(2).Rat.base-repeating();' > (1.4 > 14213197969543147208121827411167512690355329949238578680203045685279187817258883248730964467005076) > > How does Raku know √2 is approximated by 99/70 or 665857/470832? > Does not Raku just throw a binary algorithm at any number you > feed sqrt? > The floating point unit in your computer receives the 2 and returns a floating point approximation of √2. Raku then uses the algorithm I linked to in my last email to give you the 99/70. > also, what exactly am I look at with (1.4 142857)? Is > this a way of saying that 1.4 is the rational part and > 142857 the irrational part? > No, Raku doesn't know anything about irrational numbers. As soon as you obtain the return value of `sqrt(2)` in Raku, you got a rational approximation to √2 and no part of the program knows that you wanted to compute an irrational number. The irrationality is gone, it was all in your head. You are dealing with this rational number that is "close" to √2. > What is also confusing is when a number does not repeat, > what is .base-repeating() trying to tell me? Is does not repeat? > > 2/3 is 0.6666666. > $ p6 'say (2/3).Rat.base-repeating();' > (0. 6) > > Does that mean that the 6 repeats? > Yes. > and > > $ p6 'say (99/70).base-repeating();' > (1.4 142857) > > means that 142857 also repeats (it does not), but > that it is best it can figure out with the precision > it has? > What are you talking about? It does repeat. I suggest you take a piece of paper and compute the decimal digits of 99/70 by hand until you are convinced that it is 1.4 and then an endless stream of 142857 repeating. If afterwards you trust Raku again, try `(99/70).base(10, 1000)` to get the first thousand decimal digits of that fraction printed. > And it it can not find a repeat, why does it not say so? > If you did the pen and paper exercise above, you know how the algorithm goes and that it is very easy to see when you've found the repeat and when you haven't. Above, there was a repeat that was easily found. The documentation says that if the repeat cannot be found within a thousand digits, the repeating part in the return value of &base-repeating will be "???". I've found this to be false. The source code of the method does not have such precautions and the limit is certainly not 1000 decimals. Try for example 1/1019 which has a group of 1018 repeating decimals. [ Maybe the number-theoretically inclined subscribers here will figure out how I found this example. ] Curiously, the old design docs [1] mandate a buffer of 100_000 to look for repeating digits. Pre-christmas versions of Rakudo apparently did have this check but "sanity", as a comment in the Rakudo sources called it, was removed in March 2015 [2] :-) As it currently stands [3], Rakudo will exhaust all memory to try to find the repeating group if it has to. (Note that all rational numbers have this repeating group -- you know this if you did the exercise -- so the search is never in vain, but it *is* attack surface for a DoS.) > And why am I getting zero back from > $ p6 'say sqrt(2).Rat.base-repeating() - (665857/470832).base-repeating();' > 0 > The return value of &base-repeating is a list. You are subtracting two lists which actually gets you the difference of their lengths. Since both lists have two elements (all lists returned by that function do) you get zero: > sqrt(2).Rat.base-repeating - sqrt(10000000).Rat.base-repeating 0 > Also, what is the algebraic precedence of the operation? In > (665857/470832).base-repeating() > > is (665857/470832) solved first or is (665857/470832) a special > number (Rat) that is fed to .base-repeating? > What happens here is that the expression `665857/470832` is a Rat literal. You take this literal Rat object and call a method on it. It is not converted to a Num first if you meant that. > And what are the unboxing rules for (665857/470832)? > No idea what you mean. Regards, Tobias [1] https://github.com/Raku/old-design-docs/blob/180b534/S32-setting-library/Numeric.pod#base-repeating [2] https://github.com/rakudo/rakudo/commit/418c1f33 [3] https://github.com/rakudo/rakudo/blob/3e332a1/src/core.c/Rational.pm6#L351-L369 -- "There's an old saying: Don't change anything... ever!" -- Mr. Monk