Julia 将数组{Int64}转换为数组{Int32}时检查溢出的方法

Julia 将数组{Int64}转换为数组{Int32}时检查溢出的方法,julia,Julia,在将数组{Int64}转换为数组{Int32}时,是否有方法检查溢出 julia> x = [0,100,2^50] 3-element Array{Int64,1}: 0 100 1125899906842624 julia> int32(x) 3-element Array{Int32,1}: 0 100 0 我知道一个简单的方法是检查all(typemin(Int32)。

在将数组{Int64}转换为数组{Int32}时,是否有方法检查溢出

julia> x = [0,100,2^50]
3-element Array{Int64,1}:
                0
              100
 1125899906842624

julia> int32(x)
3-element Array{Int32,1}:
   0
 100
   0
我知道一个简单的方法是检查
all(typemin(Int32)。
。但我正在寻找一种更有效的方法


编辑:

我试图比较一个经过开发但不太优雅的函数
g

f(x::Array{Int64, 1}) = all(typemin(Int32) .< x .< typemax(Int32))
function g(x::Array{Int64, 1})
    a = typemin(Int32)
    b = typemax(Int32)
    for z in x
        if !(a<z<b)
            return false
        end
    end
    return true
end
x = convert(Array, (2^31-10000):(2^31));
@time for i in 1:1000; f(x); end
@time for i in 1:1000; g(x); end

我发现直接检查法更快。正如您在上面发现的,内存使用可能是原因。因此,在这种情况下,您可以将便利性与运行速度交换,从而获得更好的性能

假设 您只关心数组{Int64}转换为数组{Int32}时是否会出错。当这个数字大于2^32时,情况显然就是这样

julia> int32(2^42)
0
但是试图表示大于2^31-1的任何内容也是一个问题,因为使用了2的补码

julia> x = 2^31 - 1
2147483647

julia> int32(x) == x
true

julia> y = 2^31
2147483648

julia> int32(y) == y
false
比较 我用于比较的两个函数是

function check1(x) 
   all(typemin(Int32) .< x .< typemax(Int32))
end

function check2(x)
   ok = true;
   const min = -2^31
   const max = 2^31 - 1;

   for i = 1:length(x)
      v = x[i]
      if v > max || v < min 
         ok = false;
         break;
      end
   end
   ok
end
修饰 如果使用@inbounds宏,速度会持续增加约60%

   @inbounds v = x[i]
新成果

julia> @time for i = 1:1000 check2(z) end
elapsed time: 0.005379673 seconds (0 bytes allocated)
验证 在验证正确性时,我偶然发现了这一点

julia> u = [ 2^31 - 2; 2^31 - 1; 2^31 ]
3-element Array{Int64,1}:
 2147483646
 2147483647
 2147483648


julia> for n in u println(check1([n])) end
true
false
false

julia> for n in u println(check2([n])) end
true
true
false

看起来check1不正确,2^31-1可以用32位整数表示。取而代之的是check1应该使用,有趣的是,现在默认的行为是检查而不是截断。老实说,我不确定你怎么能比这更有效。@StefanKarpinski,你是说在v0.4中?是的,输入在0.4.thx中改变了它;我认为x中v的
应该更快+1@RandyLai我也试过了,但它阻止了使用我也试过的
@simd
宏。在这种情况下,
@simd
并没有加快速度,所以我放弃了它,但当我这样做时,我并没有恢复到。。。在里面如果您尝试它,并发现它有帮助,味精回来,我会更新。
julia> @time for i = 1:1000 check2(z) end
elapsed time: 0.005379673 seconds (0 bytes allocated)
julia> u = [ 2^31 - 2; 2^31 - 1; 2^31 ]
3-element Array{Int64,1}:
 2147483646
 2147483647
 2147483648


julia> for n in u println(check1([n])) end
true
false
false

julia> for n in u println(check2([n])) end
true
true
false
function check1(x) 
   all(typemin(Int32) .<= x .<= typemax(Int32))
end