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