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

Reply via email to