Im having problems with dividing large numbers. I have a while loop that divides the number if the index is within the array limits and if its remainder is zero:
while ((i + j*arr[i]) <= lim && arr[i + j*arr[i]] % arr[i] == 0)
arr[i + j*arr[i]] /= arr[i]
end
Im using an array of Int64 on max value of arr[i]<(150*10^6)^2, even changing to Int128 doesnt help,
BigInt is out of the question because it takes too much time.
I dont understand why I get Inexact error inside the loop if it enters only if the remainder is zero.
and typemax(Int64)>max(arr)
here is the full error:
InexactError: Int64(1.8014400929875968e15)
in top-level scope at P-146-Investigating a Prime Pattern:51
in test at P-146-Investigating a Prime Pattern:39
in setindex! at base\array.jl:826
in convert at base\number.jl:7
in Int64 at base\float.jl:710
it seems to happen only after the value in the array is above (90*10^6)^2
TLDR: use ÷.
Dividing integers with the / function in Julia returns floating point numbers. Importantly, it promotes integers to floating point numbers before it does the division. For example, the number 10^16-1 is obviously divisible by three:
julia> 9999999999999999 % 3
0
However, if we try to do this division with /, we don't get the correct answer:
julia> 9999999999999999 / 3
3.3333333333333335e15
julia> using Printf
julia> @printf "%f" 9999999999999999 / 3
3333333333333333.500000
So of course, trying to store the above number in an integer array is going to throw an inexact error. But why is this? Well you're above maxintfloat(Float64). Since floating point numbers have ~15 decimal digits of precision, above this value they are no longer able to exactly represent every single integer. They start skipping (and rounding!) them. Thus you're not really dividing 10^16-1 by three, you're dividing 10^16 by three!
julia> 10^16-1
9999999999999999
julia> Float64(10^16-1)
1.0e16
Much better to use ÷ (that is, div) — not only will it handle these cases without worrying about floating point precision, but it'll also keep things as integers:
julia> 9999999999999999 ÷ 3
3333333333333333
Problem is that / operation produces float, so following = tries to assign float value to an element of the array which is of the Int type. Consider this example
> a = [11]
> b = [2]
> a[1] /= b[1]
ERROR: InexactError: Int64(5.5)
Stacktrace:
[1] Int64 at ./float.jl:710 [inlined]
[2] convert at ./number.jl:7 [inlined]
[3] setindex!(::Array{Int64,1}, ::Float64, ::Int64) at ./array.jl:849
[4] top-level scope at REPL[6]:1
So it tries to assign 5.5 to the element of the array which consists of Int.
You can do one of the following, depending on your task
> a = [11.0]
1-element Array{Float64,1}:
11.0
> b = [2.0]
> a[1] /= b[1]
5.5
div or equivalently ÷) to make a division> a = [11]
> b = [2]
> a[1] ÷= b[1]
5
As for your original question, why it produces this error, I think that since you have rather big numbers, after converting to float and the following division you get an inexact result, which cannot be converted back to Int.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With