为什么我在Julia中为这些简单的操作得到错误的结果?

car*_*985 0 floating-point julia

我已经开始使用Julia语言,但即使是基本的操作,我也很惊讶得到看似不正确的结果:

julia> 0.05*0.05
0.0025000000000000005
Run Code Online (Sandbox Code Playgroud)

julia> 1.0-0.85-0.1
0.05000000000000002
Run Code Online (Sandbox Code Playgroud)

怎么会这样?我该怎么做才能获得准确的结果?

jub*_*0bs 10

即使是基本的操作,我也很惊讶地看到不正确的结果[...]这怎么可能?

二进制IEEE-754浮点数(Julia使用的)不能精确地表示0.05,0.85和0.1之类的数字.

例如,当您0.05在Julia中书写时,机器操作的数字是非常接近实际数字0.05的数字,但不完全是 0.05.因此,你不能指望Julia表达式如此0.05*0.05评估到0.0025.

更直言不讳的例子?尝试

julia> 1-0.2-0.2-0.2-0.2-0.2
5.551115123125783e-17

julia> 0.6/0.2 == 3
false
Run Code Online (Sandbox Code Playgroud)

如果你有兴趣(即使你不是!),我强烈推荐David Goldberg的每个计算机科学家应该知道浮点运算.您可能也对我在TeX姐妹网站上的相关答案感兴趣.


我该怎么做才能获得准确的结果?

你只是在操纵理性数字吗?如果是这样,请知道Julia提供了一种合理的类型,即允许您准确表示分数的类型.

默认使用的有理类型Rational{Int64},能够表示分子和分母落在64位整数范围内的任何有理数.您可以使用此有理类型对有理数执行精确操作(禁止整数溢出):

julia> 1//20 * 1//20
1//400

julia> 1 - 17//20 - 1//10
1//20
Run Code Online (Sandbox Code Playgroud)

此外,如果你想要任意精度的有理数,你可以使用这种Rational{BigInt}类型(参见阿尔法先生的评论)

  • 当你不想处理溢出时,Julia还有一个Rational {BigInt}. (2认同)