# Why is \`promote\_type\` not applied by \`div\` with \`Int\` and \`Rational\`?

**URL:** <https://discourse.julialang.org/t/why-is-promote-type-not-applied-by-div-with-int-and-rational/130277>\
**Category:** General Usage\
**Tags:** types\
**Created:** [June 27, 2025, 12:15pm UTC](https://discourse.julialang.org/t/why-is-promote-type-not-applied-by-div-with-int-and-rational/130277 "2025-06-27T12:15:34Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [June 27, 2025, 12:15pm UTC](https://discourse.julialang.org/t/why-is-promote-type-not-applied-by-div-with-int-and-rational/130277/1 "2025-06-27T12:15:34Z")

</div>

According to the docstring of `promote_type`:

> promote\_type represents the default promotion behavior in Julia when operators (usually mathematical) are given arguments of differing types.

And:

```julia
julia> promote_type(Int, Rational{Int})
Rational{Int64}

```

However, `1 ÷ (1//2)` returns `2`, not `2//1`. In part it makes sense, because `div` always returns integers. But this is against the stated rules, isn’t it?

---

<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:** [June 27, 2025, 12:31pm UTC](https://discourse.julialang.org/t/why-is-promote-type-not-applied-by-div-with-int-and-rational/130277/2 "2025-06-27T12:31:53Z")

</div>

`1` is promoted to `1//1` and

```julia
julia> (1//1) ÷ (1//2)
2

```

Looks consistent to me. Note that promotion only affects the inputs. What output type you get is up to the operator.

---

<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:** [June 27, 2025, 1:26pm UTC](https://discourse.julialang.org/t/why-is-promote-type-not-applied-by-div-with-int-and-rational/130277/3 "2025-06-27T13:26:30Z")

</div>

> [@heliosdrm](#):
>
> But this is against the stated rules, isn’t it?

Also, promotion is the _default_. Specific methods are allowed to override this.

Often, this is done for performance reasons. For example, there is a specialized method for `complex + real` that works _as if_ both arguments were promoted to the same complex type, but is faster (because it only needs to add the real parts).

---

<div class="post-metadata">

**Author:** ![Vasily\_Pisarev](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vasily_pisarev/32/7929_2.png) [@Vasily\_Pisarev](https://discourse.julialang.org/u/Vasily_Pisarev)\
**Post date:** [June 27, 2025, 7:23pm UTC](https://discourse.julialang.org/t/why-is-promote-type-not-applied-by-div-with-int-and-rational/130277/4 "2025-06-27T19:23:04Z")

</div>

> [@GunnarFarneback](#):
>
> Looks consistent to me. Note that promotion only affects the inputs. What output type you get is up to the operator.

It is consistent in the sense that `div(::Rational{Int}, ::Rational{Int})` always produces an `Int`. But then, for two floats it returns a float:

```julia
julia> 1 ÷ 0.5
2.0

julia> 1 ÷ 0.5f0
2.0f0

```

I’d argue that it is still unexpected that sometimes `div` returns the same type as its arguments, sometimes not.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [June 27, 2025, 7:23pm UTC](https://discourse.julialang.org/t/why-is-promote-type-not-applied-by-div-with-int-and-rational/130277/5 "2025-06-27T19:23:36Z")

</div>

> [@heliosdrm](#):
>
> `2`, not `2//1`. In part it makes sense, because `div` always returns integers

For even more nuance, `div` returns integers, but not necessarily with an `Integer` type e.g. `2.0 == div(2.5, 1)`. So after the totally separate promotion of the inputs to `Rational{Int}`, an output type of `Rational{Int}` could be reasonable for `div`. It just wasn’t chosen.

---

<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:** [June 27, 2025, 8:01pm UTC](https://discourse.julialang.org/t/why-is-promote-type-not-applied-by-div-with-int-and-rational/130277/6 "2025-06-27T20:01:39Z")

</div>

> [@Vasily\_Pisarev](#):
>
> I’d argue that it is still unexpected that sometimes `div` returns the same type as its arguments, sometimes not.

It’s a reasonable argument but it has nothing to do with promotion.
