代码之家  ›  专栏  ›  技术社区  ›  Julia Learner anothershrubery

在Julia中:Float64和BigFloat的相等

  •  2
  • Julia Learner anothershrubery  · 技术社区  · 7 年前

    在Julia 1.0.0 REPL中,我得到以下结果:

    # Line 1: This make sense.  I did not expect a Float64 to equal a BigFloat.
    julia> 26.1 == big"26.1"
    false
    
    # Line 2: This surprised me when Line 1 is considered.  Again, like Line 1, I 
    # did not expect a Float64 to equal an equivalent BigFloat.
    julia> 26.0 == big"26.0"
    true
    
    # Line 3: This I expected based on Line 1 behavior.
    julia> 26.1 - 0.1 == big"26.1" - 0.1
    false
    
    # Line 4: This surprised me based on Line 1 behavior, but it might be 
    # explained based on Line 2 behavior.  It seems to imply that if a Float64 
    # can be converted to an Integer it will compare equal to an equivalent BigFloat.
    julia> 26.1 - 0.1 == big"26.1" - big"0.1"
    true
    

    似乎Julia在幕后做了一些事情,与Float64和BigFloat进行相等比较,使得第2行和第4行为真,而第1行和第3行为假。有什么建议吗?

    https://docs.julialang.org/en/v1/base/math/#Base.:==

    基于@EPo在下面的一条有用的评论,很容易将上面的所有比较都变成事实。例如,第1行和第3行在下面为真,但在上面为假:

    # Line 1 is now true.
    julia> 26.1 ≈ big"26.1"
    true
    
    # Line 3 is now true.
    julia> 26.1 - 0.1 ≈ big"26.1" - 0.1
    true
    
    2 回复  |  直到 7 年前
        1
  •  7
  •   Alex338207    7 年前

    某些浮点数可以精确表示(26.0),但不能全部表示,例如:

    julia> using Printf
    julia> @printf("%.80f",26.0)
    26.00000000000000000000000000000000000000000000000000000000000000000000000000000000
    julia> @printf("%.80f",0.1)
    0.10000000000000000555111512312578270211815834045410156250000000000000000000000000
    

    例如,小数0.5、0.25、0.125也可以用基于二进制的浮点表示法精确地表示。例如,你有:

    julia> 26.125 - 0.125 == big"26.125" - 0.125
    true
    

    但是0.1是二进制中的一个周期数,所以它是四舍五入的。

    julia> bitstring(0.1)
    "0011111110111001100110011001100110011001100110011001100110011010"
    

    最后52位表示二进制分数。( https://en.wikipedia.org/wiki/Double-precision_floating-point_format )

        2
  •  1
  •   Steven Siew    7 年前

    它们不一样的原因是因为它们不一样

    julia> using Printf
    julia> string(BigFloat("26.1")-BigFloat("26"))
    "1.000000000000000000000000000000000000000000000000000000000000000000000000000553e-01"
    julia> @printf("%.17e",Float64(26.1)-Float64(26))
    1.00000000000001421e-01
    julia> Float64(26.1)-Float64(26) > BigFloat("26.1")-BigFloat("26")
    true