davo36 - 1 month ago 8

Python Question

This has kinda been asked, but not in this way. I have a little Python program which finds continued fractions for square roots of n (1 <= n <= 10000).

I have been trying to do this in Julia and I can't see how to. Mainly because it deals with irrational numbers (sqrt(x) is irrational if x is not a perfect square, e.g. sqrt(2) = 1.414213...). So I don't think I can use the rational class.

It says here https://docs.julialang.org/en/release-0.4/manual/integers-and-floating-point-numbers/#man-arbitrary-precision-arithmetic that Julia can do arbitrary precision arithmetic with BigFloats. But they don't seem to be accurate enough.

I have also tried to use PyCall and the Decimals package in Python (from Julia), but get weird errors (I can post them if they would be helpful).

Here is my Python program which works. And my question is how to do this in Julia please?

`def continuedFractionSquareRoots():`

'''

For each number up to 100, get the length of the continued fraction

of the square root for it.

'''

decimal.getcontext().prec = 210 # Need lots of precision for this problem.

continuedFractionLengths = []

for i in range(1, 101):

# For perfect squares, the period is 0

irrationalNumber = decimal.Decimal(i).sqrt()

if irrationalNumber == int(irrationalNumber):

continue

continuedFractionLength = 0

while True:

intPart = irrationalNumber.to_integral_exact(rounding=decimal.ROUND_FLOOR)

if continuedFractionLength == 0:

firstContinuedFractionTimes2 = int(intPart*2)

continuedFractionLength += 1

if intPart == firstContinuedFractionTimes2:

# Have reached the 'period' end for this fraction

break

fractionalPart = irrationalNumber - intPart

irrationalNumber = 1 / fractionalPart

continuedFractionLengths.append(continuedFractionLength)

return continuedFractionLengths

So as you can see, I need a way of computing an exact square root and also a way to get the integer part of the number. And that's all really, apart from lots and lots of precision!

Guys, I didn't post my Julia code because I didn't want to have a small manuscript for an answer! But here it is, it works. As I said in the comments below, I used the setprecision function to set the precision to a high value and it works. I got the value 711 empirically.

`setprecision(711)`

function continuedFractionSquareRoots()

#=

For each number up to 100, get the length of the continued fraction

of the square root for it.

=#

for i=1:100

# For perfect squares, the period is 0

irrationalNumber = BigFloat(sqrt(BigFloat(i)))

if irrationalNumber == floor(irrationalNumber)

continue

end

continuedFractionLength = 0

while true

intPart = floor(irrationalNumber)

if continuedFractionLength == 0

firstContinuedFractionTimes2 = intPart*2

end

continuedFractionLength += 1

if intPart == firstContinuedFractionTimes2

# Have reached the 'period' end for this fraction

break

end

fractionalPart = irrationalNumber - intPart

irrationalNumber = BigFloat(1) / fractionalPart

end

push!(continuedFractionLengths, continuedFractionLength)

end

return continuedFractionLengths

end

So anyway, user2357112 solved it, thanks very much.

Answer Source

Just like with Python's decimal.Decimal, you can configure the precision of Julia's BigFloat:

```
setprecision(however_many_bits)
```

Note that this is in bits, unlike decimal.Decimal, because BigFloat doesn't use decimal.