Julia返回意外值:Python转Julia做ML时计算结果不符排查
Julia与Python循环测试结果不一致问题排查
问题背景
长期使用Python进行机器学习开发,为利用Julia的速度优势尝试转用,编写简单循环测试对比运行时间,但Julia实现返回意外结果。
代码对比
Julia版本
B = Array{Float64, 2}(undef, 10000,10000) function f(x) return x^2 end function g(x) return x^3 end function h(x) return x^4 end function compose(f,g,h,x) return f(g(h(x))) end for i in 1:10000 for j in 1:10000 B[i,j] = compose(f,g,h,i+j) end end println(sum(B))
Python版本
import numpy as np B = np.zeros((10000, 10000), dtype=np.float64) def f(x): return x**2 def g(x): return x**3 def h(x): return x**4 def compute(x): return f(g(h(x))) for i in range(10000): for j in range(10000): B[i, j] = compute(i+j+2) print(np.sum(B))
结果差异
- Julia版本返回值约为
8.3e22 - Python版本返回值约为
1.0e109
问题原因分析
核心问题是整数溢出:
- Julia的整数类型(默认
Int64)是固定精度的,当计算嵌套幂运算时,中间结果会超出Int64的取值范围(最大约9e18),发生溢出后得到错误的整数,最终转换为Float64时结果完全偏离预期。 - Python的
int是任意精度类型,支持极大数值运算,不会发生溢出,因此计算结果正确。
另外,Julia中用Array{Float64,2}(undef,...)初始化数组是未填充的垃圾值,但后续循环完全覆盖了所有元素,因此这不是结果错误的原因。
解决方案
只需确保运算过程中使用浮点类型避免整数溢出,有两种常用方式:
方式1:将输入参数转为浮点类型
修改循环中的调用代码,把i+j转为Float64:
B[i,j] = compose(f,g,h,Float64(i+j))
方式2:修改函数内部运算为浮点类型
调整函数,在幂运算前将输入转为浮点:
function f(x) return Float64(x)^2 end function g(x) return Float64(x)^3 end function h(x) return Float64(x)^4 end
修改后重新运行,Julia的计算结果会和Python一致(因Float64可表示极大数值,虽有精度损失但结果量级符合预期)。
内容的提问来源于stack exchange,提问作者MrTin
相关产品推荐
相关产品推荐

