# Truncating BigFloat

**URL:** <https://discourse.julialang.org/t/truncating-bigfloat/105578>\
**Category:** General Usage\
**Created:** [October 30, 2023, 4:18pm UTC](https://discourse.julialang.org/t/truncating-bigfloat/105578 "2023-10-30T16:18:47Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![putianyi888](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/putianyi888/32/32279_2.png) [@putianyi888](https://discourse.julialang.org/u/putianyi888)\
**Post date:** [October 30, 2023, 4:18pm UTC](https://discourse.julialang.org/t/truncating-bigfloat/105578/1 "2023-10-30T16:18:47Z")

</div>

During computing, I need to truncate some `BigFloat` results (still to BigFloat, just with less precision) to save memory. Is there a way to truncate BigFloat without changing the global precision?

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [October 30, 2023, 5:12pm UTC](https://discourse.julialang.org/t/truncating-bigfloat/105578/2 "2023-10-30T17:12:24Z")

</div>

You can truncate (or use e.g. round):

```julia
julia> big"1"/3
0.3333333333333333333333333333333333333333333333333333333333333333333333333333348

julia> trunc(big"1"/3, digits=30)
0.3333333333333333333333333333330000000000000000000000000000000000000000000000018

likely not what you want because the "18" in the end, but it would be the closes approximation, unless you do in base 2 (or 4, 8...), something like:

julia> round(big"1"/3, digits=30, base=2)
0.333333333022892475128173828125

Note, none of this changes the storage requirements. These all take same space, just showing shorter in decimal expansion.

You can also do:
julia> b = big"1"/3
0.3333333333333333333333333333333333333333333333333333333333333333333333333333348

old = precision(BigFloat)
setprecision(BigFloat, 30)

julia> b # apparently doesn't change already defined variables:
0.3333333333333333333333333333333333333333333333333333333333333333333333333333348

julia> b = round(big"1"/3, digits=30, base=2)
0.33333333395

julia> setprecision(BigFloat, old)

julia> b # note I changed it, otherwise would have gotten old value, and future calculations will be at the old 256 bit default:
0.33333333395

I though something like this should work temporarily, doing same as above, as from the docs, but unsure why not:

julia> setprecision(BigFloat, 30) do big"1" end
ERROR: syntax: "Base.GMP.BigInt(alloc=2, size=1, d=0x0000000004916ec0)" is not a valid function argument name around REPL[84]:1

```

I would be concerned about changing the global setting (locally) if you have many threads. It’s not mentioned in the docs, but most likely would affect all, for wanted, or unwanted…, effect.

What you might want to do is rather use ArbFloats.jl. It’s faster and defaults to fewer digits, and has more features. You could also use it with BigFloats, i.e. for your thing cast to its type and it would have its shorter default, not messing with BigFloat’s. Both defaults are settable.

One other way that might be better for you are Rationals. Of e.g. two Int64 takes only 128 bits in total, still plausible would overflow. Or of `BigInt`s, would never overflow, and potentially take less memory than for one BigFloat(?).

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [October 30, 2023, 5:17pm UTC](https://discourse.julialang.org/t/truncating-bigfloat/105578/3 "2023-10-30T17:17:54Z")

</div>

> [@putianyi888](#):
>
> Is there a way to truncate BigFloat without changing the global precision?

Just pass the `precision` parameter to the [`BigFloat` constructor](https://docs.julialang.org/en/v1/base/numbers/#Base.MPFR.BigFloat-Tuple%7BAny,%20RoundingMode%7D):

```julia
julia> x = big(pi)
3.141592653589793238462643383279502884197169399375105820974944592307816406286198

julia> BigFloat(x, precision=10) # store rounded value in 10-bit precision
3.1406

```

---

<div class="post-metadata">

**Author:** ![Palli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/palli/32/3380_2.png) [@Palli](https://discourse.julialang.org/u/Palli)\
**Post date:** [October 30, 2023, 5:30pm UTC](https://discourse.julialang.org/t/truncating-bigfloat/105578/4 "2023-10-30T17:30:46Z")

</div>

I didn’t realize this, note two things however, this is base-2 significant digits, why

```julia
julia> BigFloat(x, precision=11) # actually also correct, assuming you realize the base, and limited, but looks odd...:
3.1406

julia> x = BigFloat(x, precision=12)
3.1416

julia> x*x # but also further calculations would add bits, e.g. * doubles them, so no longer limited by 12 (nor limiting storage, still at 256):
9.86966037750244140625

```

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [October 30, 2023, 5:45pm UTC](https://discourse.julialang.org/t/truncating-bigfloat/105578/5 "2023-10-30T17:45:48Z")

</div>

One general note is that if you are doing lots of things with different precison, you probably should be using the Arb library rather than the builtin `BigFloat`.

---

<div class="post-metadata">

**Author:** ![putianyi888](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/putianyi888/32/32279_2.png) [@putianyi888](https://discourse.julialang.org/u/putianyi888)\
**Post date:** [October 30, 2023, 10:43pm UTC](https://discourse.julialang.org/t/truncating-bigfloat/105578/6 "2023-10-30T22:43:15Z")

</div>

one further question: how do I copy an array, changing the precision? Using broadcast would result in allocation:

```julia
A[1,:] = BigFloat.(B[1,:], precision=10)

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [October 31, 2023, 1:07am UTC](https://discourse.julialang.org/t/truncating-bigfloat/105578/7 "2023-10-31T01:07:59Z")

</div>

> [@putianyi888](#):
>
> Using broadcast would result in allocation:

You can use `.=` to write into a pre-allocated array like `A[1,:]`. (Be sure to [use `@views`](https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-views) if you want to avoid allocation with `B[1,:]`.) Of course, creating new `BigFloat` values will allocate anyway, since `BigFloat` scalars are heap-allocated.
