Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: round-to-nearest integer division #30099

Closed
eschnett opened this issue Nov 20, 2018 · 4 comments
Closed

Feature request: round-to-nearest integer division #30099

eschnett opened this issue Nov 20, 2018 · 4 comments

Comments

@eschnett
Copy link
Contributor

Integer division currently offers 3 rounding modes: fld, cld, and div, corresponding to the rounding modes offered by floor, ceil, and trunc (round towards minus infinity, plus infinity, and zero).

I suggest a fourth integer division function, maybe called rdd, that rounds towards the nearest integer, breaking ties towards even, corresponding to the rounding performed by round:

function rdd(x::T, y::T)::T where {T <: Integer}
    round(T, x / y)
end

... except without converting to a floating-point number.

@chethega
Copy link
Contributor

... except without converting to a floating-point number.

What is the problem of the code you wrote?

@simonbyrne
Copy link
Contributor

Rather than add a new function, we can just overload div with rounding mode arguments. See #9283

@eschnett
Copy link
Contributor Author

@chethega The code I wrote is an experiment with fixed point arithmetic, quite similar to FixedPointNumbers. To implement correct rounding after division, I had to implement an rdd function as described above. The function is non-trivial, and would benefit from low-level optimizations.

@simonbyrne Yes, overloading div seems better than yet another cryptic function name.

(This is the function I wrote:

# Correctly rounded division (breaking ties towards even)
export rdd
function rdd(x::T, y::Signed)::T where {T <: Signed}
    d, m = fldmod(x, y)::Tuple{T, T}
    a2m = abs(m << 1)
    ay = abs(y)
    if a2m > ay
        # Round up
        d += T(1)
    elseif a2m == ay
        # Break tie towards even (round up if the result is odd)
        d += d & T(1)
    end
    d
end

)

@bobcassels
Copy link
Contributor

For the benefit of those who stumble on this issue, Julia div(x, y, RoundNearest) now does this.

It would have saved me some floundering if someone had noted this and closed this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants