Calculating cos(0.9528) in BigFloat

So I (incited by some others) calculated the following

setprecision(15*10^5)
x=big(9528)/10000;
y=cos(x);
ys=string(y);
ys[306890:306931]
"459423813195289597370437889596885962619893..."

Now this is somehow wrong…The correct sequence is:
“459423813195289597370437889596885917728725…”

In fact doing one newton-iteration with the first wrong number:

yn=y;
yn=yn+(acos(yn)-x)*sqrt(1-yn^2);

gives the desired result above, which I would have assumed however to be correct in the first place…
So what is going wrong here?

is not a good way to build a BigFloat.

julia> x=big(9528.0)/10000;

julia> y=cos(x);

julia> ys=string(y);

julia> ys[306890:306931]
"459423813195289597370437889596885917728725"

Edit: Ouch, I stand corrected; promotion should work here.

These should be exactly the same. If you’re using 0.6.0 (or earlier) on Windows, you might be hitting:
https://github.com/JuliaLang/julia/issues/22758

Try using 0.6.1, as this includes MPFR 3.1.5 which fixes the issue.

2 Likes

Also, an easier way to do this is to use the big string macro:

x = big"0.9528"
1 Like

Blockquote is not a good way to build a BigFloat.
I first tried
big(0.9528) but this was completely giving me the wrong number…

Actually: x=big(9528.0)/10000
like Ralph did still gives me the wrong answer…
I’m using v0.5

So I need at least v0.6.1 ? I will try…

On v0.6.1,

julia> big(9528.0)/10000
9.527999999999999999999999999999999999999999999999999999999999999999999999999998e-01

which is the same as big"0.9528".

You shouldn’t be doing something like big(9528.0), because that first creates a Float64 9528.0, which means it may have already lost information, before converting it to a BigFloat.

Integers (up to 2^53) are represented exactly in floating-point arithmetic, so converting an exactly representable Float64 like 9528.0 to BigFloat is perfectly safe.

5 Likes

Why is big(9528)/10000 not a good way then to build a big float?

In that particular case, yes. I was talking about the general case, where one shouldn’t do big(<some float literal>) to create a BigFloat.
(I was aware that in that particular case, it didn’t lose information, but you shouldn’t be encouraging a poor programming practice, that’s confused a lot of people already)

I was wrong; big(9528) makes a BigInt and I mistakenly thought that your problem was division not done in full BigFloat precision.

Please quote your code.

Presumably they were aware of that, since they wrote big(9528.0)/10000 instead of big(0.9528)

So now that I installed 0.6.1 I tried again, but I get the same wrong answer?
Wasn’t it fixed with MPFR 3.1.5 which was implemented in 0.6.1?

What does

unsafe_string(ccall((:mpfr_get_version,:libmpfr), Ptr{Cchar}, ()))

give?

Hmm, looks like it wasn’t fixed.

Ah, never mind. It was fixed in the 3.1.6 release of MPFR. We need to upgrade…

It gives 3.1.5

Apologies: it wasn’t fixed in 3.1.5, only 3.1.6. Unfortunately, this hasn’t made it’s way into the releases yet.

When will it be out?