# Issue with BigFloat rounding

**URL:** <https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831>\
**Category:** New to Julia\
**Tags:** bigfloat, rounding, print\
**Created:** [July 9, 2024, 3:08pm UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831 "2024-07-09T15:08:51Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![chkat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chkat/32/51707_2.png) [@chkat](https://discourse.julialang.org/u/chkat)\
**Post date:** [July 9, 2024, 3:08pm UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/1 "2024-07-09T15:08:51Z")

</div>

I want to set the BigFloat(7.0687866210937500e-1) by using a precision of 15 bits and two different rounding modes (up and down). So I do:

setprecision(15)  
setrounding(BigFloat, RoundDown) # or RoundUp  
BigFloat(7.0687866210937500e-1)

and I get both times the same result: 0.706879.  
However, using the mpfr package in C I get 0.706878 and 0.706879 for rounding down and up respectively. Any ideas why this happens ?

Thanks !

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [July 9, 2024, 3:23pm UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/2 "2024-07-09T15:23:17Z")

</div>

Often when working with BigFloat literals you want to be using strings — floating point literals are immediately Float32 or Float64 before going to the BigFloat constructor. But that’s not the problem here, because you’re using fewer bits.

```Julia
julia> setprecision(15)
15

julia> BigFloat("7.0687866210937500e-1", RoundDown)
0.706879

julia> BigFloat("7.0687866210937500e-1", RoundUp)
0.706879

```

---

<div class="post-metadata">

**Author:** ![chkat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chkat/32/51707_2.png) [@chkat](https://discourse.julialang.org/u/chkat)\
**Post date:** [July 9, 2024, 3:33pm UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/3 "2024-07-09T15:33:18Z")

</div>

Thanks for your reply ! So the rounding down or up concerns only the passage from string to a Float32 or Float64 ?  
How can I get in julia the analog of MPFR\_RNDD and MPFR\_RNDU (that I use in C), when creating the BigFloat ?

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [July 9, 2024, 4:31pm UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/4 "2024-07-09T16:31:13Z")

</div>

> [@chkat](#):
>
> 7.0687866210937500e-1

This is exactly representable with a precision of 15 bits, so the rounding mode doesn’t matter (because there’s no rounding). I think this is just some kind of printing issue.

```julia-repl
julia> setprecision(10000)
10000

julia> big = BigFloat("7.0687866210937500e-1")
0.706878662109375

julia> f64 = 7.0687866210937500e-1
0.706878662109375

julia> small = BigFloat("7.0687866210937500e-1", precision = 15)
0.706879

julia> big == f64 == small
true

julia> precision.((big, f64, small))
(10000, 53, 15)

```

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [July 9, 2024, 4:38pm UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/5 "2024-07-09T16:38:03Z")

</div>

> [@chkat](#):
>
> So I do:

BTW please use code block Markdown to make your post readable. Finds instructions and other tips here:

> [@Please read: make it easier to help you](https://discourse.julialang.org/t/please-read-make-it-easier-to-help-you/14757):
>
> Welcome to the Julia Discourse! We are enthusiastic about helping Julia programmers, both beginner and experienced. This public service announcement (PSA) outlines best practices when asking for help. Following these points makes it easier for us to help you and more likely you’ll get a prompt, useful answer. Keywords are highlighted to make it easier to refer to specific points. Choose a descriptive title that captures the key part of your question, eg “plots with multiple axes” instead of …

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [July 9, 2024, 10:56pm UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/6 "2024-07-09T22:56:03Z")

</div>

> [@nsajko](#):
>
> I think this is just some kind of printing issue.

Yeah. Almost all functions in the MPFR API take rounding modes, including the output functions. So I guess everything here is as expected, although the initial post was unclear. What exactly is your goal, @chkat?

---

<div class="post-metadata">

**Author:** ![chkat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chkat/32/51707_2.png) [@chkat](https://discourse.julialang.org/u/chkat)\
**Post date:** [July 10, 2024, 10:01am UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/7 "2024-07-10T10:01:59Z")

</div>

It confuses me how it happens that the printing in C, using two different rounding modes, gives two different decimals (0.706878 and 0.706879) but in Julia there is no difference:

```julia
julia> BigFloat(7.0687866210937500e-1, RoundDown, precision=15)
0.706879

julia> BigFloat(7.0687866210937500e-1, RoundUp, precision=15)
0.706879

```

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [July 10, 2024, 10:09am UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/8 "2024-07-10T10:09:51Z")

</div>

Can you post your C-program? As noted above, the number `7.0687866210937500e-1 == 23163/2^15`, so ideally no rounding should take place as demonstrated by @nsajko above. Unless “precision” means different things in the C-program and in julia.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [July 10, 2024, 10:17am UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/9 "2024-07-10T10:17:03Z")

</div>

> [@chkat](#):
>
> the printing in C, using two different rounding modes, gives two different decimals (0.706878 and 0.706879)

This is OK, and the Julia code is also OK. I think you’re just missing (sorry for not being clear before) the distinction between printing and construction in Julia. In your C code you seem to give a rounding mode to the MPFR printing/output routines, but in Julia you don’t do that (and I’m not sure if it’s possible to do currently). Thus the different behavior.

NB: in your Julia examples the printing happens automatically/implicitly because of the REPL.

What is your goal here? Why do you need rounding modes for printing?

---

<div class="post-metadata">

**Author:** ![chkat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chkat/32/51707_2.png) [@chkat](https://discourse.julialang.org/u/chkat)\
**Post date:** [July 10, 2024, 10:19am UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/10 "2024-07-10T10:19:23Z")

</div>

```C
#include<mpfr.h>

int main(){
    mpfr_t a;
    mpfr_init2(a, 15);
    mpfr_set_d(a, 7.0687866210937500e-1, MPFR_RNDD);
    mpfr_out_str(stdout,10, 0, a, MPFR_RNDD); // gives 7.06878e-1
    mpfr_out_str(stdout,10, 0, a, MPFR_RNDU); // gives 7.06879e-1
}

```

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [July 10, 2024, 10:44am UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/11 "2024-07-10T10:44:30Z")

</div>

Ah, ok. So in the C-program the float isn’t rounded, but you specify that the output should be 10 characters wide. Consequently, some decimals may have to be suppressed. The rounding specifies what should be done with the preceding decimal. Should it be rounded up or down?

In julia, you specify how the `Float64` should be moved into a `BigFloat` of precision 15. It’s not necessary to do any rounding, it fits exactly with a 15 bit significand. So no rounding occurs. The `BigFloat` is created.

Now, julia prints the result of the last operation. It gets a `BigFloat`, the same `BigFloat` regardless of what rounding you specified, and prints it with whatever rules for printing it has. Some looking around seems to indicate that a call to `string_mpfr(x, "%Re")` is done, followed by `_prettify_bigfloat`, whatever that is.

---

<div class="post-metadata">

**Author:** ![chkat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chkat/32/51707_2.png) [@chkat](https://discourse.julialang.org/u/chkat)\
**Post date:** [July 10, 2024, 12:41pm UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/12 "2024-07-10T12:41:44Z")

</div>

Just because you mentioned it, in

```C
mpfr_out_str(stdout,10, 0, a, MPFR_RNDD);

```

the 10 is the base, not the number of characters.

So, if I understand well, what you and @nsajko say is that it is a printing issue.  
In Julia, `string_mpfr` in turn calls the C-function `mpfr_asprintf` but that does not take the rounding as a parameter. A possible workaround to be able to obtain the rounding option when printing, would be to call the `mpfr_out_str` function via Julia, no ? But this I find complicated still, I do not know what is the corresponding type for `FILE *stream`in Julia and how I can set it to stdout.

Thanks a lot for your answers in any case !

---

<div class="post-metadata">

**Author:** ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)\
**Post date:** [July 10, 2024, 12:55pm UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/13 "2024-07-10T12:55:47Z")

</div>

The mpfr sprintf-functions takes rounding mode in their specifications, so it should be possible to use them.

> **[GNU MPFR 4.2.1](https://www.mpfr.org/mpfr-current/mpfr.html#Formatted-Output-Functions)**
>
> How to install and use GNU MPFR, a library for reliable multiple precision
> floating-point arithmetic, version 4.2.1.

---

<div class="post-metadata">

**Author:** ![chkat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chkat/32/51707_2.png) [@chkat](https://discourse.julialang.org/u/chkat)\
**Post date:** [July 10, 2024, 1:09pm UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/14 "2024-07-10T13:09:19Z")

</div>

Yes, this works, thanks a lot ! I can edit the format specifier “%Re” to include the rounding:

```julia
julia> using Base.MPFR

julia> MPFR.string_mpfr(x, "%Re")
"7.06879e-01"

julia> MPFR.string_mpfr(x, "%RDe")
"7.06878e-01"

julia> MPFR.string_mpfr(x, "%RUe")
"7.06879e-01"

```

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [July 10, 2024, 3:09pm UTC](https://discourse.julialang.org/t/issue-with-bigfloat-rounding/116831/15 "2024-07-10T15:09:01Z")

</div>

Just keep in mind that technically, this API isn’t supported. That is, there’s a chance it could stop working after an update of Julia. Personally I think that’s not very likely to happen soon, but keep it in mind.

Formally, if you were to use `MPFR.string_mpfr` in a package meant for use by others, you should whitelist tested versions of Julia in the package’s Project.toml, instead of relying on Semver.
