gpt4 book ai didi

julia - 将 Array{Int64} 转换为 Array{Int32} 时检查溢出的方法

转载 作者:行者123 更新时间:2023-12-02 01:44:56 25 4
gpt4 key购买 nike

在将 Array{Int64} 转换为 Array{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) .< x .< typemax(Int32)) 。但我正在寻找一种更有效的方法。


编辑:

我试图比较一个 devectozied 但不太优雅的函数 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

事实证明,g 使用的内存更少,因此比 f 快得多:

julia> @time for i in 1:1000; f(x); end
elapsed time: 0.046384046 seconds (13186456 bytes allocated)

julia> @time for i in 1:1000; g(x); end
elapsed time: 0.015128743 seconds (7824 bytes allocated)

最佳答案

我发现直接检查方法更快。就像您在上面发现的那样,内存使用可能是原因。所以在这种情况下,可以用方便换取运行速度,获得更好的性能。

假设

您只关心 Array{Int64} 在转换为 Array{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

结果

check2 会更快,因为它会在发现 1 个错误值后立即停止,但即使在最坏的情况下也会更快

julia> z = convert(Array{Int64},ones(10000));


julia> @time for i = 1:1000 check2(z) end
elapsed time: 0.008574832 seconds (0 bytes allocated)


julia> @time for i = 1:1000 check1(z) end
elapsed time: 0.036393418 seconds (13184000 bytes allocated)

点缀

如果使用@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 应该使用 <=

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

关于julia - 将 Array{Int64} 转换为 Array{Int32} 时检查溢出的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26201230/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com