# Promote/widen numerical types under +, \*, sqrt, log

**URL:** <https://discourse.julialang.org/t/promote-widen-numerical-types-under-sqrt-log/8137>\
**Category:** General Usage\
**Tags:** question\
**Created:** [January 3, 2018, 6:21pm UTC](https://discourse.julialang.org/t/promote-widen-numerical-types-under-sqrt-log/8137 "2018-01-03T18:21:40Z")\
**Posts on this page:** 7\
**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:** [January 3, 2018, 6:21pm UTC](https://discourse.julialang.org/t/promote-widen-numerical-types-under-sqrt-log/8137/1 "2018-01-03T18:21:40Z")

</div>

I have a tuple of numerical types. I am looking for the type that would result after combining these types with `+`, `*`, `sqrt`, `log`. Is there a function to do this?

Context: I am writing a function (too complex for an MWE here, generated code) that uses these operations, and I want type stability. Primarily it would be called with `Float64`, but other float types and the occasional `Integer` should work, too.

I could use `promote_type`, except that `log(::Int) isa Float64`. I can work around this with something like

```julia
julia> function promote_alg(Ts...)
           S = promote_type(Ts...)
           S <: Integer ? promote_type(S, Float64) : S
       end
promote_alg (generic function with 2 methods)

julia> promote_alg(Int, Float64, Float32)
Float64

julia> promote_alg(Float16, Float32, Float32)
Float32

julia> promote_alg(Int, Int, Int8)
Float64

```

but I wonder if this has a name in `Base`.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [January 3, 2018, 6:30pm UTC](https://discourse.julialang.org/t/promote-widen-numerical-types-under-sqrt-log/8137/2 "2018-01-03T18:30:56Z")

</div>

There are no hard-coded promotion-like methods for this. This works most of the time:

```julia
julia> Base.return_types((x,y)->log(x)*y, (Int,Int))
1-element Array{Any,1}:
 Float64

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [January 3, 2018, 6:33pm UTC](https://discourse.julialang.org/t/promote-widen-numerical-types-under-sqrt-log/8137/3 "2018-01-03T18:33:40Z")

</div>

In LinAlg, it is typically done something like:

```julia
typeof(sqrt(one(T) * one(T)))

```

This tends to be computed at compile time.

See [https://github.com/JuliaLang/julia/blob/15c467354e46821959dd0336bba5c569448b085f/base/linalg/qr.jl#L238](https://github.com/JuliaLang/julia/blob/15c467354e46821959dd0336bba5c569448b085f/base/linalg/qr.jl#L238) for an example.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [January 3, 2018, 6:53pm UTC](https://discourse.julialang.org/t/promote-widen-numerical-types-under-sqrt-log/8137/4 "2018-01-03T18:53:04Z")

</div>

There’s also `promote_op`:

```julia
julia> Base.promote_op(log, Int)
Float64

julia> Base.promote_op(+, Int, Float64)
Float64

```

---

<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 3, 2018, 7:05pm UTC](https://discourse.julialang.org/t/promote-widen-numerical-types-under-sqrt-log/8137/5 "2018-01-03T19:05:14Z")

</div>

> [@Tamas\_Papp](#):
>
> I want type stability

That should require knowing the result type.

---

<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 3, 2018, 7:17pm UTC](https://discourse.julialang.org/t/promote-widen-numerical-types-under-sqrt-log/8137/6 "2018-01-03T19:17:15Z")

</div>

> [@yuyichao](#):
>
> That should require knowing the result type.

Precisely. I am accumulating various results, initialized with a `zero(T)` and a `one(T)`. I want to calculate `T` to not have variables change type during the calculation.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [January 3, 2018, 7:44pm UTC](https://discourse.julialang.org/t/promote-widen-numerical-types-under-sqrt-log/8137/7 "2018-01-03T19:44:09Z")

</div>

Potentially relevant: [Ridiculous idea: types from the future](https://discourse.julialang.org/t/ridiculous-idea-types-from-the-future/5457) (in which the easiest suggestion turned out be letting `map` do all the hard work of figuring out a nice stable return type).
