在Julia里计算“1.2+0.21”的结果有问题啊

julia> 1.2 + 0.12

1.3199999999999998

1 个赞

这个不算问题吧 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,但是运行效率自然就低了。

2 个赞

请问约等号在文档中有吗?我没发现,但是你这句代码的确是可以运行的。

还有请问约等号怎么在键盘上打出来的呢?我现在只能切换到中文输入法,然后打 约等于 选择这个符号。:smiley:

对于不知道怎么输入的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).

文档的第一行就会告诉你怎么输入。:wink:

受教了,看文档看到了下边这句话,但是看到≈没考虑到它是unicode输入,还以为是julia的关系运算符:sweat:

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这本书

1 个赞

没有什么好的方法避免。如果用浮点算数就会出现这种问题。不过数值分析这学科几乎就是研究如何避免那种问题(数值不稳定性)。一般的会用到的算法都是证明过数值稳定性的,所以不用太担心这个问题。比如说LU分解(解正方形矩阵的方法)就会用pivoting来解决大部分数值稳定性问题。http://www4.ncsu.edu/~kksivara/ma505/handouts/lu-pivot.pdf

嘛。。。难的问题就是难,比如说https://en.wikipedia.org/wiki/Wilkinson%27s_polynomial

1 个赞
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
1 个赞

rationalize(0.25)
julia是支持分数的,分数是没有误差,当然,开方,无理数进入运算,又会隐式转换成浮点了

QQ%E5%9B%BE%E7%89%8720180817194430