Why does Julia rounds 0.3 down in my code?
julia> setrounding(BigFloat, RoundUp)
MPFRRoundUp::MPFRRoundingMode = 2julia> BigFloat(0.3)
0.299999999999999988897769753748434595763683319091796875
Why does Julia rounds 0.3 down in my code?
julia> setrounding(BigFloat, RoundUp)
MPFRRoundUp::MPFRRoundingMode = 2julia> BigFloat(0.3)
0.299999999999999988897769753748434595763683319091796875
The rounding happens to 0.3, which is of type Float64, no?
Try BigFloat("0.3")
and see if that’s better.
Thank you, now it is working the way I expect.
julia> setrounding(BigFloat, RoundUp)
MPFRRoundUp::MPFRRoundingMode = 2julia> BigFloat(“0.3”)
0.3000000000000000000000000000000000000000000000000000000000000000000000000000017
Here Julia is also rounding down, can you help me again?
julia> setrounding(BigFloat, RoundUp)
MPFRRoundUp::MPFRRoundingMode = 2julia> BigFloat(3/10)
0.299999999999999988897769753748434595763683319091796875
I think your mental model of the order of operations is still a bit off. When you run BigFloat(3 / 10)
, the first thing that happens is computing 3 / 10
. That operation is not affected in any way by the context of being inside a call to BigFloat
. But once 3 / 10
has run, the approximation error that confuses you has already been introduced and can’t ever be undone by calling BigFloat
. In fact, none of your examples so far have anything to do with calling setrounding(BigFloat, RoundUp)
: you’re just seeing the effects of applicative order evaluation. To see it more clearly, spend time understanding what happens here:
function f(x)
println("f!")
x
end
function g(x)
println("g!")
x
end
f(g(1))
You should do something like BigInt(3) / BigInt(10)
or big"3" / big"10"
.
BigFloat(3//10)
would also work as 3//10
is a Fraction
which is exact.
Float64
uses a binary representation, and it represents a discrete, not continuous set of numbers. 3/10
cannot be represented by a binary number with a finite number of bits. So when you type 0.3
or 3/10
, you get the binary number that can be represented as a Float64
and is closest to three tenths. Then you are converting this approximation to a BigFloat
.
You don’t see the problem here
julia> BigFloat(1/8)
0.125
because one eighth can be represented exactly as a Float64
.
Thank you for explaining, now I understand better how evaluation works in Julia.
Yes, BigFloat(3//10) works, I got the output I wanted
julia> setrounding(BigFloat, RoundUp)
MPFRRoundUp::MPFRRoundingMode = 2julia> BigFloat(3//10)
0.30000000000000000000000000000000000015
When I type any of the following expressions: ‘4.1’, ‘8.1’, ‘129.0’, Julia evaluates then as Float64. Is there any macros that makes Julia evaluate those expressions as BigFloat? Because not only is writing ‘4.1’ more comfortable than writing 'BigFloat(“4.1”), but also makes my code more readable.
You don’t need a macro, just big"4.1"
That is actually implemented as the @big_str
macro: Metaprogramming · The Julia Language
Oh, that’s awesome! Thanks for sharing!