Skip to content

round ties behaviour #8750

Closed
Closed
@simonbyrne

Description

This has come up before (#5983), but probably deserves its own issue. How should round handle ties, that is, values with fractional part of 1/2.

The two most common options are:
a) round ties away from zero: round(0.5) = 1.0, round(1.5) = 2.0.
b) round ties to even (aka banker's rounding): round(0.5) = 0.0, round(1.5) = 2.0.

LLVM provides an intrinsic for (a), but this typically requires multiple CPU instructions, and doesn't vectorize (see #8364). On the other hand (b) often corresponds to a native CPU instruction (e.g. table 4-15 of the Intel developer manual), but I don't know if LLVM offers a way to access it. (UPDATE: rint can be used, but depends on rounding mode).

The IEEE spec requires that we offer both, but doesn't have anything to say about names or interface.

Here is what other languages do:

Language a) Ties away from zero b) Ties to even Other
C (1999+) / C++ (2007+) round and variants via rint/nearbyint (depends on global rounding mode) , roundeven in future
Python 2.x: round 3+: round
Matlab/Octave round
R round
Mathematica Round
.NET (C#, F#, VB) via optional argument Math.Round
Java round: ties to +Inf
JavaScript round: ties to +Inf
Fortran (77+) ANINT
ALGOL ROUND (though not specified in standard)
Common Lisp fround
Scheme round
Emacs lisp fround
Haskell round
OCaml does not have a round function
Clojure round: ties to +Inf
Erlang round
Racket round
Ruby round
Rust round
Go does not have a Round function
Lua does not have a round function
Pascal ISO: round Free Pascal: round GNU Pascal: Round machine dependent
Modula 2 round implementation defined.
Perl does not have a round function
PHP round via optional argument other modes available (toward zero, to odd)
OpenGL roundEven round is up to implementation (presumably whatever is fastest).
OpenCL round rint (regardless of rounding mode)
Ada Rounding Unbiased_Rounding Machine_Rounding: whatever is most efficient.
APL No round?
AppleScript via rounding as taught in school option round
SAS ROUND ROUNDE
PostScript round
COBOL ROUNDED clause via options
D round (changed in dlang/phobos@91c38b4)
Forth ISO: FROUND
Tcl round (clarified in bug report)
Smalltalk rounded
Prolog SICStus: round ISO: round ties to +Inf
Delphi Round
Xpath round-half-to-even round: ties to +Inf
SQL ROUND (mostly, though varies)

My summary:

  • Older languages typically use (a).
  • Those without a focus on floating point either copy C or don't implement it.
  • Lisps and functional languages seem to prefer (b).
  • Java and JavaScript are bizarre (particularly Java pre-v7).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions