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

math: add a Round function #4594

Closed
gopherbot opened this Issue Dec 28, 2012 · 25 comments

Comments

Projects
None yet
@gopherbot

gopherbot commented Dec 28, 2012

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)
}
@remyoudompheng

This comment has been minimized.

Show comment
Hide comment
@remyoudompheng

remyoudompheng Dec 29, 2012

Contributor

Comment 1:

What would this function be supposed to do?
Contributor

remyoudompheng commented Dec 29, 2012

Comment 1:

What would this function be supposed to do?
@rsc

This comment has been minimized.

Show comment
Hide comment
@rsc

rsc Dec 29, 2012

Contributor

Comment 2:

Floating point numbers don't have digits. 
The bar for being useful needs to be pretty high to be in the Go math package. We
accepted most of what's in the C library but we're not going to take all the routines
from other libraries. The Javascript round is a 1-liner: int(f+0.5).

Status changed to WontFix.

Contributor

rsc commented Dec 29, 2012

Comment 2:

Floating point numbers don't have digits. 
The bar for being useful needs to be pretty high to be in the Go math package. We
accepted most of what's in the C library but we're not going to take all the routines
from other libraries. The Javascript round is a 1-liner: int(f+0.5).

Status changed to WontFix.

@gopherbot

This comment has been minimized.

Show comment
Hide comment
@gopherbot

gopherbot Jan 2, 2013

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.

gopherbot commented Jan 2, 2013

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.
@chespinoza

This comment has been minimized.

Show comment
Hide comment
@chespinoza

chespinoza Jul 15, 2013

Comment 4:

Some news about this Issue?

chespinoza commented Jul 15, 2013

Comment 4:

Some news about this Issue?
@rsc

This comment has been minimized.

Show comment
Hide comment
@rsc

rsc Jul 15, 2013

Contributor

Comment 5:

The issue is marked "won't fix".
Contributor

rsc commented Jul 15, 2013

Comment 5:

The issue is marked "won't fix".
@matthewrankin

This comment has been minimized.

Show comment
Hide comment
@matthewrankin

matthewrankin Mar 11, 2015

@rsc As a new gopher, not seeing a round function in the math package also tripped me up. The one-liner int(f+0.5) only works for positive values, which I assume is one reason JavaScript provides the Math.round() method to properly round numbers to the nearest integer.

I'd like to see this issue reconsidered, but in the meantime I'll use the following function. I'm only a new gopher, so I respect the core contributors' decision. But for those of us coming from Python, JavaScript, or Ruby, this may be a tripping hazard, albeit a small one.

func Round(val float64) int {
    if val < 0 {
        return int(val-0.5)
    }
    return int(val+0.5)
}

For those gophers wanting to round a float64 to a float64 with a given precision, here are two gists:

matthewrankin commented Mar 11, 2015

@rsc As a new gopher, not seeing a round function in the math package also tripped me up. The one-liner int(f+0.5) only works for positive values, which I assume is one reason JavaScript provides the Math.round() method to properly round numbers to the nearest integer.

I'd like to see this issue reconsidered, but in the meantime I'll use the following function. I'm only a new gopher, so I respect the core contributors' decision. But for those of us coming from Python, JavaScript, or Ruby, this may be a tripping hazard, albeit a small one.

func Round(val float64) int {
    if val < 0 {
        return int(val-0.5)
    }
    return int(val+0.5)
}

For those gophers wanting to round a float64 to a float64 with a given precision, here are two gists:

@minux

This comment has been minimized.

Show comment
Hide comment
@minux

minux Mar 11, 2015

Member

FYI, there is also a one-liner version of round(float64) int:
http://play.golang.org/p/iTYytKn6HA

func round(f float64) int {
return int(f + math.Copysign(0.5, f))
}

Unfortunately, math.Copysign couldn't be inlined by the
current gc implementation.

Member

minux commented Mar 11, 2015

FYI, there is also a one-liner version of round(float64) int:
http://play.golang.org/p/iTYytKn6HA

func round(f float64) int {
return int(f + math.Copysign(0.5, f))
}

Unfortunately, math.Copysign couldn't be inlined by the
current gc implementation.

@matthewrankin

This comment has been minimized.

Show comment
Hide comment
@matthewrankin

matthewrankin Mar 11, 2015

@minux Thanks for the info. I have much to learn about Go.

matthewrankin commented Mar 11, 2015

@minux Thanks for the info. I have much to learn about Go.

@rsc rsc added this to the Go1.1 milestone Apr 14, 2015

@rsc rsc removed the go1.1 label Apr 14, 2015

@fastest963

This comment has been minimized.

Show comment
Hide comment
@fastest963

fastest963 Aug 27, 2015

Contributor

The function above breaks for 0.49999999999999997

Updated function: http://play.golang.org/p/m3d40AQVS6

func round(f float64) int {
    if math.Abs(f) < 0.5 {
        return 0
    }
    return int(f + math.Copysign(0.5, f))
}
Contributor

fastest963 commented Aug 27, 2015

The function above breaks for 0.49999999999999997

Updated function: http://play.golang.org/p/m3d40AQVS6

func round(f float64) int {
    if math.Abs(f) < 0.5 {
        return 0
    }
    return int(f + math.Copysign(0.5, f))
}
@tsuna

This comment has been minimized.

Show comment
Hide comment
@tsuna

tsuna Apr 19, 2016

Contributor

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.

Contributor

tsuna commented Apr 19, 2016

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.

@griesemer

This comment has been minimized.

Show comment
Hide comment
@griesemer

griesemer Apr 20, 2016

Contributor

@tsuna: I appreciate the sentiment. That said, I think it wouldn't be as simple as just adding a generic round function as there are many ways to round (the IEEE floating point standard defines a handful of modes; and int(f+0.5) is correct for one of them). It may indeed be better to leave this to the respective application which can choose to do the optimal thing.

Contributor

griesemer commented Apr 20, 2016

@tsuna: I appreciate the sentiment. That said, I think it wouldn't be as simple as just adding a generic round function as there are many ways to round (the IEEE floating point standard defines a handful of modes; and int(f+0.5) is correct for one of them). It may indeed be better to leave this to the respective application which can choose to do the optimal thing.

@mogren

This comment has been minimized.

Show comment
Hide comment
@mogren

mogren Apr 21, 2016

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
}

mogren commented Apr 21, 2016

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
}
@rogpeppe

This comment has been minimized.

Show comment
Hide comment
@rogpeppe

rogpeppe Apr 21, 2016

Contributor

How about defining functions for all of the IEEE standard rounding modes?
On 20 Apr 2016 18:11, "Robert Griesemer" notifications@github.com wrote:

@tsuna https://github.com/tsuna: I appreciate the sentiment. That said,
I think it wouldn't be as simple as just adding a generic round function as
there are many ways to round (the IEEE floating point standard defines a
handful of modes; and int(f+0.5) is correct for one of them). It may
indeed be better to leave this to the respective application which can
choose to do the optimal thing.


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
#4594 (comment)

Contributor

rogpeppe commented Apr 21, 2016

How about defining functions for all of the IEEE standard rounding modes?
On 20 Apr 2016 18:11, "Robert Griesemer" notifications@github.com wrote:

@tsuna https://github.com/tsuna: I appreciate the sentiment. That said,
I think it wouldn't be as simple as just adding a generic round function as
there are many ways to round (the IEEE floating point standard defines a
handful of modes; and int(f+0.5) is correct for one of them). It may
indeed be better to leave this to the respective application which can
choose to do the optimal thing.


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
#4594 (comment)

@jimmyfrasche

This comment has been minimized.

Show comment
Hide comment
@jimmyfrasche

jimmyfrasche Apr 21, 2016

Member

Or a math/round package so you can say round.Method(f) instead of math.RoundMethod(f).

For that matter it could just as easily be a third party library, and probably should be—at the very least until it's complete, stabilized, well vetted, and judged idiomatic and generally useful.

Also nothing in this thread handles stuff like NaN or ±Inf, let alone regular floating point values that can't be stuffed into an int.

Member

jimmyfrasche commented Apr 21, 2016

Or a math/round package so you can say round.Method(f) instead of math.RoundMethod(f).

For that matter it could just as easily be a third party library, and probably should be—at the very least until it's complete, stabilized, well vetted, and judged idiomatic and generally useful.

Also nothing in this thread handles stuff like NaN or ±Inf, let alone regular floating point values that can't be stuffed into an int.

@brettonfinch-wf

This comment has been minimized.

Show comment
Hide comment
@brettonfinch-wf

brettonfinch-wf May 19, 2016

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.

brettonfinch-wf commented May 19, 2016

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.

@wkschwartz

This comment has been minimized.

Show comment
Hide comment
@wkschwartz

wkschwartz Jul 30, 2016

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.

wkschwartz commented Jul 30, 2016

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.

@kargakis

This comment has been minimized.

Show comment
Hide comment
@kargakis

kargakis Sep 4, 2016

Contributor

We've added our own version of the utility in Kubernetes but it would be nice to see this in stdlib. Seems useful for many people.

Contributor

kargakis commented Sep 4, 2016

We've added our own version of the utility in Kubernetes but it would be nice to see this in stdlib. Seems useful for many people.

@mdempsky

This comment has been minimized.

Show comment
Hide comment
@mdempsky

mdempsky Sep 6, 2016

Member

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.

Member

mdempsky commented Sep 6, 2016

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.

@imdanielsp

This comment has been minimized.

Show comment
Hide comment
@imdanielsp

imdanielsp Oct 17, 2016

I believe there should be a simply way for rounding numbers.

imdanielsp commented Oct 17, 2016

I believe there should be a simply way for rounding numbers.

@bradfitz

This comment has been minimized.

Show comment
Hide comment
@bradfitz

bradfitz Oct 17, 2016

Member

@dsantosp12, this is a closed issue. Comments on closed issues are generally ignored.

Also, your comments adds nothing unique. See https://golang.org/wiki/NoMeToo

Member

bradfitz commented Oct 17, 2016

@dsantosp12, this is a closed issue. Comments on closed issues are generally ignored.

Also, your comments adds nothing unique. See https://golang.org/wiki/NoMeToo

@kargakis

This comment has been minimized.

Show comment
Hide comment
@kargakis

kargakis Oct 17, 2016

Contributor

@bradfitz this implies you monitor closed issues for 👍 reactions. Do you do it at all? If so, how?

Contributor

kargakis commented Oct 17, 2016

@bradfitz this implies you monitor closed issues for 👍 reactions. Do you do it at all? If so, how?

@bradfitz

This comment has been minimized.

Show comment
Hide comment
@bradfitz

bradfitz Oct 17, 2016

Member

No, most people don't monitor, see, track, or follow-up on closed issues at all. None of our dashboards care about closed issues. I saw this email and replied, but most people don't get emails about them either.

Member

bradfitz commented Oct 17, 2016

No, most people don't monitor, see, track, or follow-up on closed issues at all. None of our dashboards care about closed issues. I saw this email and replied, but most people don't get emails about them either.

@YanhaoYang

This comment has been minimized.

Show comment
Hide comment
@YanhaoYang

YanhaoYang May 12, 2017

To round a float to arbitrary precision, this decimal package could be helpful.

YanhaoYang commented May 12, 2017

To round a float to arbitrary precision, this decimal package could be helpful.

@dansouza

This comment has been minimized.

Show comment
Hide comment
@dansouza

dansouza commented Jul 10, 2017

Why doesn't Go use the native instructions for rounding ?

@bradfitz

This comment has been minimized.

Show comment
Hide comment
@bradfitz

bradfitz Jul 10, 2017

Member

@dansouza, see #20100 (comment)

You're replying to a closed issue from 2012 from when it was decided to not (yet) add Round to the standard library.

The issue you want to read is #20100 from 2017 which was approved and will be added to Go 1.10.

I'm going to lock this issue to focus attention to #20100.

Member

bradfitz commented Jul 10, 2017

@dansouza, see #20100 (comment)

You're replying to a closed issue from 2012 from when it was decided to not (yet) add Round to the standard library.

The issue you want to read is #20100 from 2017 which was approved and will be added to Go 1.10.

I'm going to lock this issue to focus attention to #20100.

@golang golang locked and limited conversation to collaborators Jul 10, 2017

This issue was closed.

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