julia> 1.2 + 0.12
1.3199999999999998
julia> 1.2 + 0.12
1.3199999999999998
这个不算问题吧 64位浮点
我知道在误差范围之内。但是,如果我的循环很大,误差积累非常严重的,那么我最后的结果可能是错的,但是我的算法不一定是错的,那该是如何改进呢?
Julia的浮点数运算是支持IEEE754标准的,因此浮点数的代数运算不满足结合律:
julia> 0.1 + 0.2 + 0.3
0.6000000000000001
julia> 0.1 + (0.2 + 0.3)
0.6
在做累加求和等运算时,求和顺序不一致可能会导致计算结果有误差,但不会很大,Julia里提供≈
来比较:
0.1 + 0.2 + 0.3 == 0.1 + (0.2 + 0.3)
false
0.1 + 0.2 + 0.3 ≈ 0.1 + (0.2 + 0.3)
true
如果算法需要高精度,也可以使用BigFloat,但是运行效率自然就低了。
请问约等号在文档中有吗?我没发现,但是你这句代码的确是可以运行的。
还有请问约等号怎么在键盘上打出来的呢?我现在只能切换到中文输入法,然后打 约等于 选择这个符号。
对于不知道怎么输入的Unicode字符,可以直接在REPL按?
进入help mode,然后复制粘贴Unicode字符:
help?> ≈
"≈" can be typed by \approx<tab>
search: ≈
isapprox(x, y; rtol::Real=atol>0 ? 0 : √eps, atol::Real=0, nans::Bool=false, norm::Function)
Inexact equality comparison: true if norm(x-y) <= max(atol, rtol*max(norm(x), norm(y))). The default atol is zero and the default rtol
depends on the types of x and y. The keyword argument nans determines whether or not NaN values are considered equal (defaults to false).
文档的第一行就会告诉你怎么输入。
受教了,看文档看到了下边这句话,但是看到≈没考虑到它是unicode输入,还以为是julia的关系运算符
You can also get information on how to type a symbol by entering it in the REPL help, i.e. by typing
?
and then entering the symbol in the REPL (e.g., by copy-paste from somewhere you saw the symbol).
只要是你用了IEEE754 浮点标准,那就一定会有这些问题。
如果实在想要解决这个问题,就需要换一个浮点数的标准,可以参见 The End of Error: Unum Computing这本书
没有什么好的方法避免。如果用浮点算数就会出现这种问题。不过数值分析这学科几乎就是研究如何避免那种问题(数值不稳定性)。一般的会用到的算法都是证明过数值稳定性的,所以不用太担心这个问题。比如说LU分解(解正方形矩阵的方法)就会用pivoting来解决大部分数值稳定性问题。http://www4.ncsu.edu/~kksivara/ma505/handouts/lu-pivot.pdf
嘛。。。难的问题就是难,比如说Wilkinson's polynomial - Wikipedia
julia> exp(im*pi) ≈ -1
true
julia> exp(im*pi) + 1 ≈ 0
false
要注意比较的时候不要和0比。因为
julia> eps(1.)
2.220446049250313e-16
julia> eps(0.)
5.0e-324
rationalize(0.25)
julia是支持分数的,分数是没有误差,当然,开方,无理数进入运算,又会隐式转换成浮点了