# Get base10 mantissa and exponent of real (eg Float64)

**URL:** https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529
**Category:** General Usage
**Tags:** question, float
**Created:** [October 21, 2024, 11:52am UTC](https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529 "2024-10-21T11:52:29Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [October 21, 2024, 11:52am UTC](https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529/1 "2024-10-21T11:52:30Z")

</div>

What would be the recommended way of getting the **base 10** mantissa and exponent of a floating point number?

Is there a package that does this? Or should I just reparse from printed representation, as in

```julia
using Printf

function get_mantissa_exponent(x)
    str = @sprintf "%.15e" x # specialize 15 based on type
    _mantissa, exponent = split(str, 'e')
    (; mantissa = filter(!isequal('.'), _mantissa),
     exponent = parse(Int, exponent))
end

julia> get_mantissa_exponent(3.17)
(mantissa = "3170000000000000", exponent = 0)

```

---

<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 21, 2024, 12:28pm UTC](https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529/2 "2024-10-21T12:28:14Z")

</div>

> [@Tamas\_Papp](#):
>
> What would be the recommended way of getting the **base 10** mantissa and exponent of a floating point number?

It depends on what you mean by “the” base-10 mantissa and exponent. I assume you are mainly interested in binary floating-point types like `Float64` and `Float32`.

The one that is shown in the default printed representation of a `Float64` is only an approximation — it is the _shortest_ decimal representation that _rounds_ to the same `Float64` value. If this is what you want, I’m not aware of a documented API other than parsing the printed representation. If you are willing to use an undocumented API, there is [`mantissa, exponent = Base.Ryu.reduce_shortest(x)`](https://github.com/JuliaLang/julia/blob/1c67d0cfdc8ab109120dc3f0720053e509a10131/base/ryu/shortest.jl#L7).

Of course, there is an exact decimal representation too, but it typically requires a large number of digits.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [October 21, 2024, 12:39pm UTC](https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529/3 "2024-10-21T12:39:22Z")

</div>

Thanks! Sorry for not being clear, yes, I am after the printed approximation.

---

<div class="post-metadata">

### Author: ![barucden](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/barucden/32/26154_2.png) [@barucden](https://discourse.julialang.org/u/barucden)
#### Post date: [October 21, 2024, 12:40pm UTC](https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529/4 "2024-10-21T12:40:49Z")

</div>

> [@Tamas\_Papp](#):
>
> ```julia
> julia> get_mantissa_exponent(3.17)
> (mantissa = "3170000000000000", exponent = 0)
> 
> ```

Is this the result you expected? Based on the title, I would have expected mantissa `317` and exponent `-2` (or an equivalent alternative like `3170` and `-3`) because `317 * 10^-2 = 3.17`.

Coincidentally, I work on JuliaMath/Decimals.jl these days. You could use that package to parse a number and get the mantissa and exponent from the resulting `Decimal`:

```julia
using Decimals
x = parse(Decimal, "3.17")
mantissa = x.c # 317
exponent = x.q # -2

```

The package has some bugs (parsing has been fixed recently in a pending PR), but I am trying to improve it and it might already be sufficient for your case now.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [October 21, 2024, 12:53pm UTC](https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529/5 "2024-10-21T12:53:42Z")

</div>

> [@barucden](#):
>
> Is this the result you expected?

Technically you are right, but I am after a string which I can just cut off at some point and insert a decimal dot, so I am flexible.

The point of the exercise is for _printing_, into LaTeX. That is, I want to generate output like `raw"$4.92 \cdot 10^{-3}$"` and `raw"$22.71 \cdot 10^{6}$"` (engineering notation).

---

<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: [October 21, 2024, 1:10pm UTC](https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529/6 "2024-10-21T13:10:15Z")

</div>

How about a simplistic regex?

```julia
julia> replace(string((10rand())^10), r"(\d+.\d+)[ef]\+?(-?\d+)"=>s"$\1 \\cdot 10^{\2}$") |> println
$6.71626435914464 \cdot 10^{6}$

```

---

<div class="post-metadata">

### Author: ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)
#### Post date: [October 21, 2024, 2:12pm UTC](https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529/7 "2024-10-21T14:12:58Z")

</div>

Linking [related thread](https://discourse.julialang.org/t/how-to-get-the-significand-and-the-exponent-of-a-floating-point-number/29900/2).

---

<div class="post-metadata">

### Author: ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)
#### Post date: [October 21, 2024, 9:37pm UTC](https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529/8 "2024-10-21T21:37:24Z")

</div>

This works for positive floating point number. Just check if number is negative and manually insert a negative sign yourself.

```julia
julia> a = log(10, Float64(π) )
0.4971498726941338

julia> println("$(10.0^(a-trunc(a))) * 10^$(Int64(trunc(a)))")
3.1415926535897927 * 10^0

julia> a = log(10, 123.456*Float64(π) )
2.5886620743219053

julia> println("$(10.0^(a-trunc(a))) * 10^$(Int64(trunc(a)))")
3.8784846264158133 * 10^2

julia> 123.456*Float64(π)
387.84846264158153

```

---

<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: [October 21, 2024, 9:44pm UTC](https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529/9 "2024-10-21T21:44:59Z")

</div>

Doing something with a numeric `log` is _highly likely_ to have catastrophic rounding problems around powers of 10.

In my view, the best answer in this case is to use standard tooling (like `@sprintf`) and fix it up as strings — either as a split like Tamas first suggested or with a regex. Both are really fine.

---

<div class="post-metadata">

### Author: ![StevenSiew](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevensiew/32/218393_2.png) [@StevenSiew](https://discourse.julialang.org/u/StevenSiew)
#### Post date: [October 21, 2024, 9:51pm UTC](https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529/10 "2024-10-21T21:51:27Z")

</div>

I don’t think the original poster cares about rounding errors. He said

“Thanks! Sorry for not being clear, yes, I am after the printed approximation.”

I take that to mean approximation in base 10 (not approximation in base 2)

---

<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: [October 21, 2024, 9:54pm UTC](https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529/11 "2024-10-21T21:54:49Z")

</div>

The problem I was worried about isn’t small errors. I suspect that it’s possible the exponent and mantissa might round different ways. Around powers of 10 that could easily lead to a factor of 10 error — something that I suspect everyone would care about.

I might be wrong — and I think you might be doing it in a way that’s safe — but regardless it’s worrisome.

---

<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 23, 2024, 2:39pm UTC](https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529/12 "2024-10-23T14:39:51Z")

</div>

10 posts were split to a new topic: [Typst (alternative to LaTeX)](https://discourse.julialang.org/t/typst-alternative-to-latex/121652)

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [October 22, 2024, 8:54am UTC](https://discourse.julialang.org/t/get-base10-mantissa-and-exponent-of-real-eg-float64/121529/13 "2024-10-22T08:54:36Z")

</div>

> [@StevenSiew](#):
>
> I don’t think the original poster cares about rounding errors. He said
> 
> “Thanks! Sorry for not being clear, yes, I am after the printed approximation.”

You misunderstand. The “printed approximation” is how floating point numbers are printed; it is understood to be an approximation in the sense the trailing digits that solely come from base 2 to base 10 conversion are omitted, but it is accurate in the sense that it would be parsed back to the same base 2 number. This is what the module `Ryu` implements currently in base Julia, and handling it correctly is equivalent to reimplementing that. If you are interested in the complexity of the topic, see the [papers cited here](https://github.com/ulfjack/ryu?tab=readme-ov-file).

> [@mbauman](#):
>
> the best answer in this case is to use standard tooling

I agree, but it would be great to expose the API of Ryu in the long run. It is one of those niche algorithms where a lot of thought went into speed and correctness and are very useful when you need them.
