# BigFloat promotion rules and constants in functions

**URL:** <https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573>\
**Category:** New to Julia\
**Created:** [September 5, 2018, 10:02am UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573 "2018-09-05T10:02:05Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ckoe-bccms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckoe-bccms/32/1816_2.png) [@ckoe-bccms](https://discourse.julialang.org/u/ckoe-bccms)\
**Post date:** [September 5, 2018, 10:02am UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/1 "2018-09-05T10:02:05Z")

</div>

Hello everybody,

I started to experiment with BigFloats and I am not sure how to best (and with minimum manual effort) handle numerical constants in functions.

The following shows the behaviour as documented, the constant `2.0/3.0` gets not automatically promoted to BigFloat

```julia
julia> setprecision(128)
128
julia> function g_one(x)
       2.0/3.0*x
       end
g (generic function with 1 method)
julia> g_one(BigFloat(1.0))
6.666666666666666296592325124947819858789e-01

```

Of course one can do

```julia
julia> function g_two(x::T) where {T}
       a::T = 2.0
       b::T = 3.0
       a/b*x
       end
g (generic function with 1 method)
julia> g_two(BigFloat(1.0))
6.666666666666666666666666666666666666676e-01

```

but note the next (this again is as documented, promotion to BigFloat happens after 2.0/3.0 is computed in `Float64`)

```julia
julia> function g_three(x::T) where {T}
       a::T = 2.0/3.0
       a*x
       end
g (generic function with 1 method)
julia> g_three(BigFloat(1.0))
6.666666666666666296592325124947819858789e-01

```

What confuses me is now this.

Assume the function is something more complicated with a lot of numerical constants. Without rewriting (pulling out the constants, storing them in tuples while making sure they are correctly promoted) it is not possible to just switch to `BigFloat` and get a cosistent accuracy because `Float64` constants do not get promoted ?

How would I reliably and with minimum effort ensure everything has the right precision ? Is there perhaps some premade macro to cast every `Float64` constant to `BigFloat` ? I suspect @generated could be used for this, but this to me appears to be a bit of an overkill for some quick experiment, especially since I never had any contact with it beyond knowing it exists.

Finally, one might observe that in something like `2.0*x` where `x` is a `BigFloat` this promotion behaviour is completely invisible which might lead to some confusion if one did not read the documentation.

Best Regards

---

<div class="post-metadata">

**Author:** ![gpapo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gpapo/32/1857_2.png) [@gpapo](https://discourse.julialang.org/u/gpapo)\
**Post date:** [September 5, 2018, 10:41am UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/2 "2018-09-05T10:41:27Z")

</div>

Have a look at [ChangePrecision.jl](https://github.com/stevengj/ChangePrecision.jl)

---

<div class="post-metadata">

**Author:** ![ckoe-bccms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckoe-bccms/32/1816_2.png) [@ckoe-bccms](https://discourse.julialang.org/u/ckoe-bccms)\
**Post date:** [September 5, 2018, 10:46am UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/3 "2018-09-05T10:46:44Z")

</div>

Thank you. That looks interesting, although it does not appear to do `BigFloat` out of the box.

Another vaguely related question:

```julia
z=range(BigFloat(0.0),stop=BigFloat(2.0),step=BigFloat(0.1))
0.0:1.000000000000000055511151231257827021181583404541015625e-01:1.9000000000000001054711873393898713402450084686279296875

```

So `range()` does not honor `BigFloat` at all ? That would be an unpleasant suprise if true and highly inconsistent.

EDIT: OK, `LinRange()` appears to be working. I am not sure what the intended behaviour of `range()` or the preferred function are.

---

<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:** [September 5, 2018, 11:42am UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/4 "2018-09-05T11:42:21Z")

</div>

`range` honours BigFloat - it’s just that BigFloat conversion from floating point literals is icky, since they get converted to floating point first during parsing of the julia source:

```julia
help?> BigFloat
# snip
BigFloat(x)

Create an arbitrary precision floating point number. x may be an Integer, a Float64 or 
a BigInt. The usual mathematical operators are defined for this type, and results are
promoted to a BigFloat.

Note that because decimal literals are converted to floating point numbers when parsed, 
BigFloat(2.1) may not yield what you expect. You may instead prefer to initialize 
constants from strings via parse, or using the big string literal.

julia> BigFloat(2.1)
2.100000000000000088817841970012523233890533447265625

julia> big"2.1"
2.099999999999999999999999999999999999999999999999999999999999999999999999999986

```

And the range using `big"..."`:

```julia
julia> range(big"0.0",stop=big"2.0",step=big"0.1")
0.0:1.000000000000000000000000000000000000000000000000000000000000000000000000000002e-01:2.0

```

The same can be done using `parse(BigFloat, "0.1")`.

---

<div class="post-metadata">

**Author:** ![ckoe-bccms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckoe-bccms/32/1816_2.png) [@ckoe-bccms](https://discourse.julialang.org/u/ckoe-bccms)\
**Post date:** [September 5, 2018, 11:57am UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/5 "2018-09-05T11:57:58Z")

</div>

> [@Sukera](#):
>
> since they get converted to floating point first:

OK, I see. I was assuming BigFloat(x) and big"x" were equivalent. The the parser always does `Float64` first and calls `BigFloat()` on the result. And yes,

```julia
julia> parse(BigFloat,readline())
0.1
1.000000000000000000000000000000000000000000000000000000000000000000000000000002e-01

```

However, ignoring ChangePrecision.jl, solving my original problem becomes even more awkward

```julia
julia> function g(x::T) where {T}
       a::T = 0.1
       a*x
       end
g (generic function with 1 method)
julia> g(BigFloat(1.0))
1.000000000000000055511151231257827021181583404541015625e-01

julia> function g(x::T) where {T}
       a= big"0.1"
       a*x
       end
g (generic function with 1 method)
julia> g(BigFloat(1.0))
1.000000000000000000000000000000000000000000000000000000000000000000000000000002e-01

```

This cannot be right ? And the what I understand of ChangePrecision.jl indicates that its approach will not work ?

Edit: Of course

```julia
julia> function g(x::T) where {T}
       a::T = 10.0
       1.0/a*x
       end
g (generic function with 1 method)

julia> g(BigFloat(1.0))
1.000000000000000000000000000000000000000000000000000000000000000000000000000002e-01

```

but, really …

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [September 5, 2018, 12:46pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/6 "2018-09-05T12:46:51Z")

</div>

It would probably be possible to to get a ChangePrecision approach to work more ideally if the parser stored the literals as strings or in some decimal format, but that would be quite a big change and very possibly require painful trade-offs in other respects.

What you can do now is to use constructions like `2 * x / 3` or `x * 2 / 3` or employ rationals, `2//3 * x`.

---

<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:** [September 5, 2018, 12:50pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/7 "2018-09-05T12:50:48Z")

</div>

> [@GunnarFarneback](#):
>
> It would probably be possible to to get a ChangePrecision approach to work more ideally if the parser stored the literals as strings or in some decimal format, but that would be quite a big change and very possibly require painful trade-offs in other respects.

ChangePrecision doesn’t have much trouble with literals, because it converts them with `parse(T, string(literal))` and the [grisu algorithm](https://github.com/kring/grisu.net) generally outputs the desired string version of floating-point literals even for decimals (that is, it outputs a string equivalent to the one that you used to type the literal). The problem is constructors (like `range`) … it is not possible to get it to recognize all possible functions that could default to returning `Float64`.

ChangePrecision is intended as a hack so that you can take informal user scripts and quickly experiment with a different precisions. If you want to write long-term precision-agnostic code, e.g. library code, then you need to be aware of types and write code that uses your argument types to construct values.

---

<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:** [September 5, 2018, 12:56pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/8 "2018-09-05T12:56:04Z")

</div>

You’re still using Floating Point literals. It doesn’t matter if they get converted via assignment to a declared `BigFloat` or directly passed to `BigFloat()` - the conversion happens at the parsing stage, long before any value assignment is taking place.

As it is right now, your code is not generic since you have those literals still present. The promotion works - but because of the smaller precision than a “normal” `BigFloat`, you still get all those inaccuracies of a regular Float, because they are introduced before converting them to a `BigFloat`. You probably want something like this (EDIT: this is effectively what ChangePrecision.jl does, if I understand correctly):

```julia
julia> function g(x::T) where {T <: AbstractFloat}
         a = parse(T, "0.1")
         a*x
       end

```

Yes, it’s cumbersome to convert all basic literals like `0.1` to the above if you want to use literals and possibly also `BigFloat`s - and it should probably be made easier/possible without having to change so much code. Maybe the behaviour of the parsing can be changed to not wrap floating point literals in a Float (maybe even only when surrounded by `BigFloat(...)`)? I’d be interested to see some proposals on this, but I think that’s probably pretty tricky to do.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [September 5, 2018, 1:00pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/9 "2018-09-05T13:00:56Z")

</div>

> [@stevengj](#):
>
> ChangePrecision doesn’t have much trouble with literals, because it converts them with `parse(T, string(literal))` and the [grisu algorithm](https://github.com/kring/grisu.net) generally outputs the desired string version of floating-point literals even for decimals (that is, it outputs a string equivalent to the one that you used to type the literal).

Right, I stand corrected.

---

<div class="post-metadata">

**Author:** ![ckoe-bccms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckoe-bccms/32/1816_2.png) [@ckoe-bccms](https://discourse.julialang.org/u/ckoe-bccms)\
**Post date:** [September 5, 2018, 1:39pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/10 "2018-09-05T13:39:50Z")

</div>

> [@Sukera](#):
>
> julia\> function g(x::T) where {T \<: AbstractFloat} a = parse(T, “0.1”) a\*x end

Ah, yes ! I believe that is what I wanted to know, how to dispatch correctly. That is indeed generic, and one could switch then to DoubleFloats or ArbFloats (or whatever decimal type), too, I believe.

Of course ideally that 0.1 should be replaced by a rational number (i.e. 1/10) to make the intention clear if one is known.

Thank you all for your answers !

---

<div class="post-metadata">

**Author:** ![ckoe-bccms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckoe-bccms/32/1816_2.png) [@ckoe-bccms](https://discourse.julialang.org/u/ckoe-bccms)\
**Post date:** [September 5, 2018, 1:42pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/11 "2018-09-05T13:42:40Z")

</div>

> [@stevengj](#):
>
> and the [grisu algorithm](https://github.com/kring/grisu.net) generall

That is interesting. I will read it as soon as I am back at work, apparently this does not use a conversion tolerance. Thank you !

---

<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:** [September 5, 2018, 1:44pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/12 "2018-09-05T13:44:51Z")

</div>

Careful, `1/10 != 1//10`! Also, using `1//10` could promote everything to `Rational`:

```julia
julia> function g(x::T) where {T}
          a = 1//10
          a*x
       end
g (generic function with 1 method)

julia> g(big"10")
1//1

julia> typeof(ans)
Rational{BigInt}

```

That may be more suitable for what you want though, as it still does what you expect for BigFloat:

```julia
julia> g(big"10.0")
1.0

julia> typeof(ans)
BigFloat

```

Bear in mind, there can still be problems.

```julia
julia> g(big"0.1")
9.999999999999999999999999999999999999999999999999999999999999999999999999999995e-03

```

In general, sticking to the explicit parsing with the given argumenttype is most generic.

---

<div class="post-metadata">

**Author:** ![ckoe-bccms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckoe-bccms/32/1816_2.png) [@ckoe-bccms](https://discourse.julialang.org/u/ckoe-bccms)\
**Post date:** [September 5, 2018, 1:58pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/13 "2018-09-05T13:58:53Z")

</div>

> [@Sukera](#):
>
> Careful, `1/10 != 1//10` ! Also

OK, big"1" is a BigInt. Yes, together with the built-in rational type that can go wrong.

I originally thought of something like (in case a mathematical rational number is known at all for a constant)

```julia
function g(x::T) where {T}
tenth=parse(T,"1")/parse(T,"10")
tenth*x
end

```

Of course `tenth` could be a tuple element to store multiple constants.

I am not sure it makes sense. Probably a bit verbose, but eventually it makes it clear what the original number was. I will have to think about now that I know how to dispatch.

---

<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:** [September 5, 2018, 5:46pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/14 "2018-09-05T17:46:13Z")

</div>

> [@Sukera](#):
>
> In general, sticking to the explicit parsing with the given argumenttype is most generic.

Also very slow.

If you want to ensure a floating-point result you could do something like:

```julia
function g(x::T) where {T<:Number}
    tenth::float(real(T)) = 1//10
    return tenth*x
end

```

---

<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:** [September 5, 2018, 5:59pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/15 "2018-09-05T17:59:51Z")

</div>

Well, not _that_ much though:

```julia
julia> function g(x::T) where {T<:Number}
           tenth::float(real(T)) = 1//10
           return tenth*x
       end
g (generic function with 1 method)

julia> function f(x::T) where {T <: AbstractFloat}
           a = parse(T, "0.1")
           a*x
       end
f (generic function with 1 method)

julia> @benchmark g($x)
BenchmarkTools.Trial:
  memory estimate: 448 bytes
  allocs estimate: 8
  --------------
  minimum time: 287.234 ns (0.00% GC)
  median time: 290.780 ns (0.00% GC)
  mean time: 348.059 ns (9.57% GC)
  maximum time: 124.752 μs (99.65% GC)
  --------------
  samples: 10000
  evals/sample: 282

julia> @benchmark f($x)
BenchmarkTools.Trial:
  memory estimate: 228 bytes
  allocs estimate: 5
  --------------
  minimum time: 402.985 ns (0.00% GC)
  median time: 407.960 ns (0.00% GC)
  mean time: 467.812 ns (7.00% GC)
  maximum time: 173.055 μs (99.70% GC)
  --------------
  samples: 10000
  evals/sample: 201

```

But yours will scale better with bigger literals, because parsing that string is slow.

---

<div class="post-metadata">

**Author:** ![ckoe-bccms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckoe-bccms/32/1816_2.png) [@ckoe-bccms](https://discourse.julialang.org/u/ckoe-bccms)\
**Post date:** [September 5, 2018, 7:06pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/16 "2018-09-05T19:06:20Z")

</div>

I had expected that it would get slower. On the other hand using `BigFloat` is already (as expected) so slow compared to `Float64` that I do not really care about speed, at the moment at least 🙂 On top, I see now that I can pull out rational constants only in a few equations.

Still, this is of course very useful for future reference.

I just wanted to test how large the floating point rounding impact on some nasty convergence issue I have actually is. It turns out it most likely is the dominating factor (unless of course I messed something else up). Next step would probably to try DoubleFloats or ArbFloats, may be I can do a bit better than simply demonstrating the likely cause of the problem.

So, this whole discussion was highly appreciated from my side !

---

<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:** [September 5, 2018, 8:21pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/17 "2018-09-05T20:21:18Z")

</div>

If you’re caring about an error term, maybe Measurements.jl is for you:

> **[GitHub - JuliaPhysics/Measurements.jl: Error propagation calculator and...](https://github.com/JuliaPhysics/Measurements.jl)**
>
> Error propagation calculator and library for physical measurements. It supports real and complex numbers with uncertainty, arbitrary precision calculations, operations with arrays, and numerical i...

---

<div class="post-metadata">

**Author:** ![ckoe-bccms](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ckoe-bccms/32/1816_2.png) [@ckoe-bccms](https://discourse.julialang.org/u/ckoe-bccms)\
**Post date:** [September 5, 2018, 8:54pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/18 "2018-09-05T20:54:45Z")

</div>

No, will not help I believe.

It is the circular restricted three-body problem, so an ODE. More specifically, the Poincare sections, see [here](http://adsabs.harvard.edu/full/1966IAUS...25..157H). This has two singularities at the location of the heavy masses in its potential. Regularization (in my case Thiele-Burrau) can shift them to infinity. The regularization effectively casts cartesian coordinates (and momenta) into expressions which consist of trigonometric and hyperbolic functions with complex arguments (if one wants to work with the Hamiltonian, so canonical positions and momenta, these are extra lengthy). Apparently the rounding error noise is about 1e-12 relative, and of course it gets summed up for longer trajectories. With `BigFloats` even with only 72 bit this, as far as I have tested it by now, is much lower and integration is much more stable.

Basically, this has been done to death by NASA in the 1960s as prerequisite to the Apollo program. They appear to have been using recursion instead of Runge-Kuttas or similar, see for example [here](https://ntrs.nasa.gov/search.jsp?R=19690008692) and [here](https://ntrs.nasa.gov/search.jsp?R=19680013800), to solve that. I was arrogant and thought modern high order ODE solvers (DifferentialEquations.jl) with step size control would work quite easy. That was wrong in that large part of the problem appears to be floating point accuracy depending on the trajectory and Jacobi integral value.

Or I still have an error somewhere, although I can reproduce most of Brouckes stable solutions. I have no idea how Henon did his calculation.

Edit: To be more precise, I can reproduce Brouckes solutions with stability indices up to about 200 for about two periods, but some trajectories have indices in the 40000 range which is a challenge.

---

<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:** [September 5, 2018, 9:39pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/19 "2018-09-05T21:39:05Z")

</div>

I’m definitely way in over my head here, I’m just a lowly CS student 😄

Still, I’ve dug around a bit and found [this](https://ntrs.nasa.gov/archive/nasa/casi.ntrs.nasa.gov/19670016363.pdf) paper from Zurich, sponsored by NASA and IBM containing an ALGOL 60 procedure to compute what (I think, if I understood correctly) you’re looking for. Might be completely useless (you probably already know about it), but they’re using Runge-Kutta (fourth order, see p.53) and also write about how a smaller integration step doesn’t pay off, “because the error produced by the ephemeris then becomes dominant. However, the integration with a smaller step would improve the balance of the energy equation.” (p.57)

So, either they ran into the same problem you did and didn’t have enough bits to go further (in which case, yay?) or I’m way too tired to read papers and shouldn’t dig into things I’m not even remotely familiar with 😃

---

<div class="post-metadata">

**Author:** ![platawiec](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/platawiec/32/31914_2.png) [@platawiec](https://discourse.julialang.org/u/platawiec)\
**Post date:** [September 5, 2018, 10:33pm UTC](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573/20 "2018-09-05T22:33:28Z")

</div>

You may already by familiar with these options, but just in case, have you tried the [symplectic integrators?](http://docs.juliadiffeq.org/latest/solvers/dynamical_solve.html)

Alternatively, you can try [manifold conversation and projection](http://docs.juliadiffeq.org/latest/features/callback_library.html#Manifold-Conservation-and-Projection-1).

According to DiffEq’s [FAQ](http://docs.juliadiffeq.org/latest/basics/faq.html#Numerical-Error-1), it’s better to use callbacks for energy conservation. The [Henon-Heiles Energy Conservation Benchmark](http://nbviewer.jupyter.org/github/JuliaDiffEq/DiffEqBenchmarks.jl/blob/master/DynamicalODE/Henon-Heiles_energy_conservation_benchmark.ipynb) and [Quadrupole Boson Hamiltonian Energy Conservation Benchmark](http://nbviewer.jupyter.org/github/JuliaDiffEq/DiffEqBenchmarks.jl/blob/master/DynamicalODE/Quadrupole_boson_Hamiltonian_energy_conservation_benchmark.ipynb) go into more detail.

Hopefully that helps!

**EDIT** : In fact, I just noticed you mentioned Henon’s calculation, so you should definitely give these benchmarks a look!

[Next page](https://discourse.julialang.org/t/bigfloat-promotion-rules-and-constants-in-functions/14573.md?page=2)
