Julia 将数组{Int64}转换为数组{Int32}时检查溢出的方法
在将数组{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)。
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