# BigFloat number conversion problem

**URL:** <https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807>\
**Category:** New to Julia\
**Created:** [January 19, 2019, 7:59am UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807 "2019-01-19T07:59:06Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![feierbach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feierbach/32/7698_2.png) [@feierbach](https://discourse.julialang.org/u/feierbach)\
**Post date:** [January 19, 2019, 7:59am UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/1 "2019-01-19T07:59:06Z")

</div>

Here is the problem in a nutshell:  
julia\> BigFloat(3.825)  
3.82500000000000017763568394002504646778106689453125  
julia\>BigFloat(3825//1000)  
3.825000000000000000000000000000000000000000000000000000000000000000000000000007

In the first one it looks like a Float64 is taking place before BigFloat gets it and the rest is noise.

---

<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:** [January 19, 2019, 8:31am UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/2 "2019-01-19T08:31:06Z")

</div>

Use the [`big"..."`](https://docs.julialang.org/en/v1/base/numbers/#Base.@big_str) non-standard literal, eg

```julia
julia> big"3.825"
3.825000000000000000000000000000000000000000000000000000000000000000000000000007

```

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [January 19, 2019, 3:26pm UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/3 "2019-01-19T15:26:12Z")

</div>

> [@feierbach](#):
>
> In the first one it looks like a Float64 is taking place before BigFloat gets it and the rest is noise.

That’s true - as far as I remember, this already happens at parsing level, long before the call converts its argument.

---

<div class="post-metadata">

**Author:** ![feierbach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feierbach/32/7698_2.png) [@feierbach](https://discourse.julialang.org/u/feierbach)\
**Post date:** [January 19, 2019, 8:29pm UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/4 "2019-01-19T20:29:36Z")

</div>

Seems like a problem to me. Any sane way to get around this other than turning the number into a rational

---

<div class="post-metadata">

**Author:** ![feierbach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feierbach/32/7698_2.png) [@feierbach](https://discourse.julialang.org/u/feierbach)\
**Post date:** [January 19, 2019, 8:41pm UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/5 "2019-01-19T20:41:36Z")

</div>

Related to this if you try to convert the 3.825 into a rational you do not get 3825//1000 or reduced 153//40 so the fault is at the string to Float64 conversion since it should be exact in binary. I see 2 problems, a Float64 conversion that is wrong and a Float64 conversion that shouldn’t happen.

---

<div class="post-metadata">

**Author:** ![feierbach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feierbach/32/7698_2.png) [@feierbach](https://discourse.julialang.org/u/feierbach)\
**Post date:** [January 19, 2019, 9:56pm UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/6 "2019-01-19T21:56:28Z")

</div>

Thanks Tamas for big"8.325" that works correctly  
julia\>big"8.325"  
3.825000000000000000000000000000000000000000000000000000000000000000000000000007  
In the online manual they show big() which would indicate  
big(3.825) or big(“3.825”)  
julia\> big(3.825)  
3.82500000000000017763568394002504646778106689453125  
julia\> big(“3.825”)  
ERROR: MethodError: no method matching big(::String)  
Closest candidates are:  
big(::Type{Complex{T\<:Real}}) where T\<:Real at complex.jl:969  
big(::Type{#s561} where #s561\<:Integer) at gmp.jl:403  
big(::Type{#s561} where #s561\<:Rational) at gmp.jl:404  
…  
Stacktrace:  
[1] top-level scope at none:0  
There is some language inconsistency here that probably needs to be addressed.

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [January 19, 2019, 10:36pm UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/7 "2019-01-19T22:36:00Z")

</div>

> [@feierbach](#):
>
> In the online manual they show big() which would indicate  
> big(3.825) or big(“3.825”)

Could you please post a link to where you found this? If you want to create a `BigFloat` from a regular string, a correct way would be this:

```julia
julia> BigFloat("3.825")
3.825000000000000000000000000000000000000000000000000000000000000000000000000007

```

the `big()` function converts an existing _number_ to its “big” (i.e. maximum precision) representation, according to its type:

```julia
julia> big(1)
1

julia> typeof(big(1))
BigInt

julia> big(1.0)
1.0

julia> typeof(big(1.0))
BigFloat

```

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [January 19, 2019, 11:30pm UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/8 "2019-01-19T23:30:59Z")

</div>

> [@feierbach](#):
>
> Related to this if you try to convert the 3.825 into a rational you do not get 3825//1000 or reduced 153//40 so the fault is at the string to Float64 conversion since it should be exact in binary

Why do you say that 3.825 should be exact in binary?

I don’t think it is: 3.825 = \frac{153}{40} = \frac1{2^3} \left(30 + \frac35\right), and the binary representation of \frac35 has an infinite cyclic sequence (much like the infamous 1/10):

\frac35 =(0.1001100110011\ldots)\_2

So the mantissa cannot be represented exactly with a finite number of bits.

---

<div class="post-metadata">

**Author:** ![feierbach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/feierbach/32/7698_2.png) [@feierbach](https://discourse.julialang.org/u/feierbach)\
**Post date:** [January 20, 2019, 8:31pm UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/9 "2019-01-20T20:31:52Z")

</div>

@ffevotte you are certainly correct. I should have expanded it in binary before making such a dumb statement.

That blunder aside, I still think there is an issue using BigFloat but don’t have any good suggestion for a clean solution. However, there might be some way to pass the initial string as well as the converted number and let the function decide which to take and convert. I know that sounds very clumsy but using big"3.825" just seems very wrong and inconsistent language-wise.

big is under base.big in the [julialang.org](http://julialang.org) manual and yes, BigFloat(“3.825”) also works and is better than using big"3.825" which is rather hokey syntax.

---

<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:** [January 21, 2019, 7:21am UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/10 "2019-01-21T07:21:20Z")

</div>

> [@feierbach](#):
>
> big"3.825" which is rather hokey syntax

It is part of the supported API. If anything, the odd one out is `BigFloat(::AbstractString)`, as other float types just have a `(try)parse`, but it makes sense since one may need to specify the precision.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [January 21, 2019, 7:34am UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/11 "2019-01-21T07:34:19Z")

</div>

Note that you can get a rational with

```
rationalize(3.825)

```

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [January 21, 2019, 8:29am UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/12 "2019-01-21T08:29:59Z")

</div>

> [@dpsanders](#):
>
> Note that you can get a rational with
> 
> ```julia
> rationalize(3.825)
> 
> ```

Yes, but in this case, 3.825 gets first parsed as a `Float64` (and therefore rounded), and only then is it converted to a rational. Depending on the tolerance given to `rationalize`, one may not always get \frac{153}{40} as one might expect.

This happens to work, because the round-off error caused by the conversion to `Float64` is compensated by the approximation in `rationalize`:

```julia
julia> rationalize(3.825, tol=1e-15)
 153//40

```

When decreasing the tolerance, `rationalize` produces a better approximation of `Float64(3.825)`, but not of 3.825 itself.

```julia
julia> rationalize(3.825, tol=1e-20)
 538290589893019//140729565985103

```

Whereas for `big"3.825"` and with the same level of tolerance, `rationalize` produces the “correct” result (which, again, is not guaranteed, but happens to be the case because round-off errors compensate)

```julia
julia> rationalize(big"3.825", tol=1e-20)
153//40

```

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [January 21, 2019, 9:27am UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/13 "2019-01-21T09:27:16Z")

</div>

> [@feierbach](#):
>
> I know that sounds very clumsy but using big"3.825" just seems very wrong and inconsistent language-wise.

I’m not sure I understand what you find inconsistent. Would you rather have a special syntax understood by the parser to define `BigFloat` literals, like we have `1.0f0` to define `Float32` literals instead of `Float64`? I might be missing something, but I would say that `Float32` is the exception here (perhaps because it is both very useful and supported by the hardware).

All other numeric types that I know of (big integers, 32-bit integers on a 64-bit architecture, big floats, half-precision floats…) must be built explicitly, either using their constructor (_e.g._ `BigInt`, `Int32`, `BigFloat`…) to convert them from another numeric representation, or using `parse` to read them from a string. So all this seems rather consistent to me.

I see the `big"..."` string macro merely as syntactic sugar to avoid calling `parse` (or rather `tryparse` in this case) for `BigInt` or `BigFloat` literals.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [January 21, 2019, 12:25pm UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/14 "2019-01-21T12:25:52Z")

</div>

> [@ffevotte](#):
>
> All other numeric types that I know of (big integers, 32-bit integers on a 64-bit architecture, big floats, half-precision floats…) must be built explicitly, either using their constructor ( _e.g._ `BigInt` , `Int32` , `BigFloat` …) to convert them from another numeric representation, or using `parse` to read them from a string.

At least unsigned integers, hexadecimals, binary and octal also have special syntax: [Integers and Floating-Point Numbers · The Julia Language](https://docs.julialang.org/en/v1/manual/integers-and-floating-point-numbers/#Integers-1)

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [January 21, 2019, 1:03pm UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/15 "2019-01-21T13:03:34Z")

</div>

> [@DNF](#):
>
> At least unsigned integers, hexadecimals, binary and octal also have special syntax

True. I guess I was not explicit enough, then. What I wanted to say is that, if you want to build a numeric value of a specific type, _based on its decimal representation_\* (an important mention that I forgot), I think that you have to explicitly parse a string except for very few specific types: `Int` (32 or 64 depending on your architecture), `Float32` and `Float64`.

It’s true that you can build an `UInt` with special syntax, but then you have to change the radix and use a binary, octal or hexadecimal representation (and BTW I would consider hexadecimal, binary and octal to be number representations, not types). If you want to represent the _value_ 25 as an `UInt` (as opposed to creating a bitmask), you either have to make the conversion in your head and write `0x19` or be explicit and call the relevant constructor `UInt(25)` or `parse(UInt, "25")`.

  

* * *

\* I make the distinction here because I think most mere humans nowadays think of numeric values in terms of their decimal representations. I would even venture to say that developers (although they are much more than mere humans 😉) only depart from radix 10 in very specific situations, for example when building bitmasks (in which case the value of the number is of somewhat lesser importance…) Of course I might be wrong.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [January 21, 2019, 1:26pm UTC](https://discourse.julialang.org/t/bigfloat-number-conversion-problem/19807/16 "2019-01-21T13:26:39Z")

</div>

> [@ffevotte](#):
>
> you have to explicitly parse a string

No definitely not. The only thing you need to be explicitly about is the type.

> [@ffevotte](#):
>
> `UInt(25)`

Is by no mean parsing a string and

> [@ffevotte](#):
>
> `parse(UInt, "25")`

Don’t use this as literal.
