InexactError:Int64,即使在检查可分割性时也是如此



我在对大数字进行除法时遇到问题。我有一个while循环,如果索引在数组限制内,并且余数为零,它会对数字进行除法运算:

while ((i + j*arr[i]) <= lim && arr[i + j*arr[i]] % arr[i] == 0)
arr[i + j*arr[i]] /= arr[i]
end

Im在arr[i]<(150*10^6)^2的最大值上使用Int64的数组,即使更改为Int128也无济于事,BigInt是不可能的,因为它花费了太多时间。我不明白为什么只有当余数为零时,循环才会出现Inexact错误。和typemax(Int64)>max(arr)这是完整的错误:

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 basearray.jl:826 
in convert at basenumber.jl:7 
in Int64 at basefloat.jl:710 

它似乎只有在数组中的值高于(90*10^6)^2之后才会发生

TLDR:使用÷

使用Julia中的/函数对整数进行除法运算会返回浮点数。重要的是,它在执行除法之前将整数提升为浮点数。例如,数字10^16-1显然可以被三整除:

julia> 9999999999999999 % 3
0

然而,如果我们尝试用/进行这种划分,我们不会得到正确的答案:

julia> 9999999999999999 / 3
3.3333333333333335e15
julia> using Printf
julia> @printf "%f" 9999999999999999 / 3
3333333333333333.500000

所以,当然,试图将上面的数字存储在一个整数数组中会抛出一个不精确的错误。但为什么会这样呢?你已经超过maxintfloat(Float64)了。由于浮点数字的精度约为15位小数,超过该值后,它们将无法准确表示每一个整数。他们开始跳过(并绕过!(他们。因此,你并不是真的把10^16-1除以三,而是把10^16除以三!

julia> 10^16-1
9999999999999999
julia> Float64(10^16-1)
1.0e16

使用÷(也就是div(要好得多——它不仅可以处理这些情况而不必担心浮点精度,而且还可以保持整数形式:

julia> 9999999999999999 ÷ 3
3333333333333333

问题是/操作产生float,因此下面的=尝试将浮点值分配给Int类型的数组元素。考虑这个例子

> 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

因此,它试图将CCD_ 16分配给由CCD_ 17组成的数组的元素。

根据您的任务,您可以执行以下操作之一

  1. 以某种方式将数组声明为浮点数组
> a = [11.0]
1-element Array{Float64,1}:
11.0
> b = [2.0]
> a[1] /= b[1]
5.5
  1. 使用整数除法(div或等效的÷(进行除法
> a = [11]
> b = [2]
> a[1] ÷= b[1]
5

至于你最初的问题,为什么会产生这个错误,我认为,由于你有相当大的数字,在转换为float和下面的除法后,你会得到一个不精确的结果,无法转换回Int

使用整数除法÷/div有时会有风险——您可能会因为舍入而丢失值,甚至没有注意到。因此,在许多情况下,可以考虑使用Julia对有理数的支持。

julia> u = 9999999999999999 // 3
3333333333333333//1
julia> u % 3 == 0
true

由于有理数的存储方式,您可以期待良好的性能(尽管不如整数除法(:

julia> dump(u)
Rational{Int64}
num: Int64 3333333333333333
den: Int64 1

最新更新