# What interface to implement for \`round(x, digits=n)\` to work?

**URL:** https://discourse.julialang.org/t/what-interface-to-implement-for-round-x-digits-n-to-work/122372
**Category:** General Usage
**Tags:** interface, rounding
**Created:** [November 7, 2024, 8:26am UTC](https://discourse.julialang.org/t/what-interface-to-implement-for-round-x-digits-n-to-work/122372 "2024-11-07T08:26:56Z")
**Posts on this page:** 3
**Page:** 1

<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: [November 7, 2024, 8:26am UTC](https://discourse.julialang.org/t/what-interface-to-implement-for-round-x-digits-n-to-work/122372/1 "2024-11-07T08:26:56Z")

</div>

There is a section in the documentation that explains what methods to implement to support rounding on a new type:

> **[Interfaces · The Julia Language](https://docs.julialang.org/en/v1/manual/interfaces/#man-rounding-interface)**
>
> Documentation for The Julia Language.

Apparently, one needs to implement `round(x::ObjType, r::RoundingMode)`. The section even includes an example for an interval type:

```julia-repl
julia> struct Interval{T}
           min::T
           max::T
       end

julia> Base.round(x::Interval, r::RoundingMode) = Interval(round(x.min, r), round(x.max, r))

julia> x = Interval(1.7, 2.2)
Interval{Float64}(1.7, 2.2)

julia> round(x)
Interval{Float64}(2.0, 2.0)

```

However, this method is not enough for the keyword arguments `digits` and `sigdigits` to work:

```julia-repl
julia> round(x, digits=0)
ERROR: MethodError: no method matching round(::Interval{Float64}, ::RoundingMode{:Nearest}; digits::Int64)

julia> round(x, sigdigits=1)
ERROR: MethodError: no method matching round(::Interval{Float64}, ::RoundingMode{:Nearest}; sigdigits::Int64)

```

**What methods should I implement so that these calls work?** I can make it work by implementing

```julia
round(x::Interval, r::RoundingMode; 
      digits::Union{Integer,Nothing}=nothing, 
      sigdigits::Union{Integer,Nothing}=nothing)

```

but I am not sure if that’s intended.

---

<div class="post-metadata">

### Author: ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)
#### Post date: [November 7, 2024, 9:09am UTC](https://discourse.julialang.org/t/what-interface-to-implement-for-round-x-digits-n-to-work/122372/2 "2024-11-07T09:09:31Z")

</div>

In general I would expect you should also explicitly provide e.g. `digits`, since it’s not always obvious what it would mean to round up to n digits. (Say you want to round a `Date`. Then ‘`digits`’ might mean you want to round up to a day, week, month, etc. But there will not be any default mechanism to fall back on. (Edit: `round` is actually already canonically implemented for `Date`s, where you should just provide `Day`, `Week`, `Month`,… The keyword `digits` is not supported. 🙂 )

But in this case you can just pass through all keyword arguments to `round(::T)`.

```julia-repl
julia> Base.round(x::Interval, r::RoundingMode=RoundNearest; kwargs...) = Interval(round(x.min, r, kwargs...), round(x.max, r, kwargs...))

julia> I = Interval(1.32, 5.88)
Interval{Float64}(1.32, 5.88)

julia> round(I)
Interval{Float64}(1.0, 6.0)

julia> round(I, digits=1)
Interval{Float64}(1.3, 5.9)

```

---

<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: [November 7, 2024, 9:32am UTC](https://discourse.julialang.org/t/what-interface-to-implement-for-round-x-digits-n-to-work/122372/3 "2024-11-07T09:32:38Z")

</div>

Thank you. Yes, in the case of `Interval`, you can do that, but that’s only possible because the fields are floats for which we already have the methods with the keyword arguments implemented.

Maybe I should have been more specific in the first post. I am working on implementing rounding for the `Decimal` type ([Normal by barucden · Pull Request #88 · JuliaMath/Decimals.jl · GitHub](https://github.com/JuliaMath/Decimals.jl/pull/88)), which is a subtype of `AbstractFloat`.

The keyword arguments `digits` and `sigdigits` make sense for rounding a `Decimal`, and I have an implementation. However, I already had to add some extra methods to resolve ambiguities, and the whole thing starts to feel “awkward”, which makes me think that I am not connecting to the whole `round`-machinery as I should.
