7

I found this and this on this StackExchange as to why Mathematica rounds half to even, which means that

Round[{0.5, 1.5, 2.5, 3.5, 4.5}]

gives

{0, 2, 2, 4, 4}

but now I am interested in rounding half down, which would be a function such that

RoundDown[{7.49, 7.5, 7.51}]

gives

{7, 7, 8}

I don't think it exists since I searched a lot and didn't find anything, so I was wondering as to how would one code such a function efficiently (I need to run it some millions of times)?

viiv
  • 73
  • 4

2 Answers2

11
ClearAll[roundDown]
roundDown = Ceiling[# - 1/2] &; (* thanks: @MichaelE2 *)

roundDown @ {7.4999, 7.5, 7.51}
(* or roundDown[{7.4999, 7.5, 7.51}] *)

{7, 7, 8}

kglr
  • 394,356
  • 18
  • 477
  • 896
  • That's short and efficient, thanks! As a note for future users it also works with roundDown[{7.4999, 7.5, 7.51}] – viiv Jan 03 '18 at 06:48
  • @viiv, my pleasure. Thank you for the accept. – kglr Jan 03 '18 at 07:00
  • 1
    @viiv One might want to use 1/2 instead of 0.5. E.g. try rd1 = Ceiling[# - 1/2] &; rd2 = Ceiling[# - 0.5] &; {rd1[3/2 + 2^-53], rd2[3/2 + 2^-53]}. – Michael E2 Feb 20 '18 at 12:17
  • @MichaelE2, very good point. – kglr Feb 20 '18 at 12:27
  • Indeed, it's all about those edge cases. Fortunately I never went that deep into the precision, I was limited to floats. – viiv Feb 20 '18 at 12:46
2

Adding a note to kglr's answer, consider

n = 50*4.65

roundDown[n]

233

An improvement could be

rd[n_] := Ceiling[With[{r = Round[#]}, r + Chop[# - r]] &[n - 0.5]]

rd[n]

232

Chris Degnen
  • 30,927
  • 2
  • 54
  • 108