math: add a Round function

by bunge@google.com:

Would it be possible to add a math.Round(n float64, digits uint) float64 function that
rounds a floating point number to the specified number of digits? This has been
discussed on golang-nuts here:
https://groups.google.com/d/topic/golang-nuts/ITZV08gAugI/discussion

I am not entirely convinced by the required digit argument. Perhaps we should have:

Round(n float64) float64 {
  return RoundDigits(n, 0)
}

9 thoughts on “math: add a Round function

  1. Comment 3 by bunge@google.com:

    Another option is to round half away from zero, so this would be:
    if n < 0 {
      return math.Ceil(n-0.5)
    }
    return math.Floor(n+0.5)
    This is arguably no less complex than math.Abs, although I assume the latter is in the
    Go library due to its inclusion in the C library.
    If I have some time I will code up a Go rounding module with different rounding
    strategies.
  2. Having seen at least 3 different people try to write a Round() function and fail in various ways (sometimes subtle, sometimes not so subtle like @rsc above suggesting to use int(f+0.5), which doesn’t work for negative values), I do wonder why this isn’t included in the math package. Sure, “the bar for being useful needs to be pretty high”, but when most people don’t get simple maths right… And this often needs to be both correct and fast.

  3. You don’t even need to use math.Abs and math.Copysign, I use:

    func round(f float64) int {
        if f < -0.5 {
            return int(f - 0.5)
        }
        if f > 0.5 {
            return int(f + 0.5)
        }
        return 0
    }
    
  4. I feel like a basic round function would be very helpful. There is no need for every user of the language to have to build a round function (even if it is “trivial” to implement). Sound like an easy addition that would provide value.

  5. For what it’s worth, this (IMO injudiciously) closed ticket is the second result when you Google “how to round numbers in golang”. Here’s my vote for bringing this ticket back and adding a func Round(float64) float64 function to the math package.

  6. How about defining functions for all of the IEEE standard rounding modes?

    IEEE defines 5 rounding modes: TiesToEven, TiesToAway, TowardPositive, TowardNegative, TowardZero.

    In the context of rounding an existing float value to a nearby integer value, TowardPositive, TowardNegative, and TowardZero are equivalent to package math’s existing Ceil, Floor, and Trunc functions, respectively.

    That leaves just TiesToEven and TiesToAway. It’s not obvious to me that TiesToEven is useful in the context of integral rounding.