When programming before, I sometimes get problem like:
a=3.1415926
b=3.1415926
a==b
it output false, why? check it out and found b is actually 3.1415926000000001 something like that.
so I always have to replace a==b with something like abs(a-b)<10e-10
I noticed Julia has many builtin functions like eps(), prevfloat(), nextfloat(), isequal()
Can any of these functions avoid the above situation? or Julia has something else to do this? Thanks.
See e.g. Comparing Floating Point Numbers, 2012 Edition | Random ASCII – tech blog of Bruce Dawson if you want to read more about floating point comparisons.
Also, this should never be the case in any languages. It’s possible that some don’t show enough digits but none of them should generate different results from the same assignment.
Wow, that’s good reading. Thanks!
Thanks, looks like you guys all suggesting this in Julia to judge if two floats are equal?:
abs(a-b)<n*eps(float), with n an appropriate small number .
Not really. Best practice is to think about the context and then use the relevant comparison. Eg even ==
can be the best choice for unit testing a simple calculation constructed to be exact.
See eg isapprox
, which has two relevant parameters and is generally a reasonable solution.
Also, for the record,
julia> 3.1415926000000001 == 3.1415926
true
in Julia (not enough precision to represent that last digit), so you must have been doing something different. Generally, unless they are rounded in the context of a container, different Float64
s will print differently.
Not really.
FWIW, you need to define you problem first.
If your problem is having numbers that prints the same compares equal, then that’s already the case in julia.
If your problem is to have numbers that prints the same in certain other languages compares equal, well, you need to figure out how those languages print numbers. It’s most likely just printing a fixed number of digits in which case you are approximately comparing with a fixed relative tolerrance
If you have a real problem with some known rounding error, you should just check for that tolerance.
Wow, I didn’t even try that!!! That happened to be 1e-16 smaller than eps(Float64)
Thanks, I see!
I find this particularly painful in matrices
julia> A = [ 1.0 2.0; 3.0 4.0 ]; invA = inv(A)
2×2 Array{Float64,2}:
-2.0 1.0
1.5 -0.5
julia> println(invA)
[-1.9999999999999996 0.9999999999999998; 1.4999999999999998 -0.4999999999999999]
julia> B=(x->round(x,digits=14)).(invA)
2×2 Array{Float64,2}:
-2.0 1.0
1.5 -0.5
julia> println(B)
[-2.0 1.0; 1.5 -0.5]
julia> C=(x->round(x,sigdigits=14)).(invA)
2×2 Array{Float64,2}:
-2.0 1.0
1.5 -0.5
julia> println(C)
[-2.0 1.0; 1.5 -0.5]