Function round

6365 views
Skip to first unread message

Archos

unread,
Dec 31, 2011, 6:02:34 PM12/31/11
to golang-nuts
Is there any similar function to "round" in JavaScript?
To return the value of a number rounded to the nearest integer.


https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Math/round

Daniel Jo

unread,
Dec 31, 2011, 6:31:06 PM12/31/11
to Archos, golang-nuts
The closest I can think of is:

i = int(math.Floor(f+0.5))

-Daniel

Michael Jones

unread,
Jan 1, 2012, 11:08:01 AM1/1/12
to Daniel Jo, golang-nuts, Archos

Works so long as you like rounding down when f is negative...

Johann Höchtl

unread,
Jan 1, 2012, 12:47:19 PM1/1/12
to golan...@googlegroups.com
This one should work:

func round(val float64, prec int) float64 {

    var rounder float64
    intermed := val * math.Pow(10, float64(prec))

    if val >= 0.5 {
        rounder = math.Ceil(intermed)
    } else {
        rounder = math.Floor(intermed)
    }

    return rounder / math.Pow(10, float64(prec))
}

result := int(round( <yourvalue> , 0))

Chris Hines

unread,
Jan 2, 2012, 12:39:14 PM1/2/12
to golan...@googlegroups.com, Daniel Jo, Archos
I had the same reaction initially. Since the OP asked about the JavaScript implementation of "round", though I checked what that does and curiously it does round down when f is negative.

Jan Mercl

unread,
Oct 16, 2012, 1:54:34 PM10/16/12
to Dawid Polak, golan...@googlegroups.com
On Tue, Oct 16, 2012 at 5:59 PM, Dawid Polak <da...@mentax.pl> wrote:
> In this code is small bug, and it should look like that:
>
> // Round return rounded version of x with prec precision.
> func Round(x float64, prec int) float64 {
> var rounder float64
> pow := math.Pow(10, float64(prec))
> intermed := x * pow
> _, frac := math.Modf(intermed)
>
> if frac >= 0.5 {
> rounder = math.Ceil(intermed)
> } else {
> rounder = math.Floor(intermed)
> }
>
> return rounder / pow
> }
>
> Example: http://play.golang.org/p/6SnMqR9-9_

http://play.golang.org/p/MlSteRZVX3

-j

Gerard

unread,
Oct 16, 2012, 3:32:59 PM10/16/12
to golan...@googlegroups.com

Op zondag 1 januari 2012 00:02:34 UTC+1 schreef Archos het volgende:
Is there any similar function to "round" in JavaScript?
To return the value of a number rounded to the nearest integer.


// round value - convert to int64
func Round(value float64) int64 {
if value < 0.0 {
value -= 0.5
} else {
value += 0.5
}
return int64(value)
}
 

Rory McGuire

unread,
Oct 17, 2012, 3:23:29 AM10/17/12
to golan...@googlegroups.com
@Gerard missed the precision
Here is a combination of the solutions by Gerard and Jan Merci:


PS: Anyone know for definite why Round(123.424999999999993, 2) gets wrong result?

Johann Höchtl

unread,
Oct 17, 2012, 5:39:38 AM10/17/12
to golan...@googlegroups.com


Am Sonntag, 1. Januar 2012 00:02:34 UTC+1 schrieb Archos:
Is there any similar function to "round" in JavaScript?
To return the value of a number rounded to the nearest integer.


My implementation:

func round(val float64, prec int) float64 {

var rounder float64
intermed := val * math.Pow(10, float64(prec))

if val >= 0.5 {
rounder = math.Ceil(intermed)
} else {
rounder = math.Floor(intermed)
}

return rounder / math.Pow(10, float64(prec))
}
 

Gerard

unread,
Oct 17, 2012, 6:33:55 AM10/17/12
to golan...@googlegroups.com
Op woensdag 17 oktober 2012 09:23:29 UTC+2 schreef Rory McGuire het volgende:
@Gerard missed the precision

No I didn't. The question was about rounding to the nearest integer.

Gerard

Peter S

unread,
Oct 17, 2012, 9:15:35 AM10/17/12
to Rory McGuire, golan...@googlegroups.com
On Wed, Oct 17, 2012 at 4:23 PM, Rory McGuire <rjmc...@gmail.com> wrote:
@Gerard missed the precision
Here is a combination of the solutions by Gerard and Jan Merci:


PS: Anyone know for definite why Round(123.424999999999993, 2) gets wrong result?


Float types have limited precisions, so you will inevitably get incorrect results beyond a certain number of digits. If that is not acceptable for your application, you probably shouldn't be using float types at all.

In your specific example, due to the lack of precision, float64 cannot distinguish between 123.424999999999993 and 123.425000000000001: http://play.golang.org/p/PAf89JrpYt

See also: http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

Shameless plug: you could try using the library I wrote for multi-precision decimal arithmetic (project page: http://code.google.com/p/godec/ ) . Actually it doesn't (yet) have a method for "just rounding", but dividing by 1 with scale 2 and half up rounding should give you the desired result. (I might add a separate method for just rounding later, although I think in most cases where rounding is needed it is in combination with a division anyway.)

Here is an example:

package main

import "fmt"
import "code.google.com/p/godec/dec"

func main() {
        d1, ok1 := new(dec.Dec).SetString("123.424999999999993")
        d2, ok2 := new(dec.Dec).SetString("123.425000000000001")
        if !ok1 || !ok2 {
                panic("Invalid number")
        }
        one := dec.NewDecInt64(1)
        r1 := new(dec.Dec).Quo(d1, one, dec.ScaleFixed2, dec.RoundHalfUp)
        r2 := new(dec.Dec).Quo(d2, one, dec.ScaleFixed2, dec.RoundHalfUp)
        fmt.Println(r1, r2)
}


Peter

 

On Tuesday, 16 October 2012 21:32:59 UTC+2, Gerard wrote:

Op zondag 1 januari 2012 00:02:34 UTC+1 schreef Archos het volgende:
Is there any similar function to "round" in JavaScript?
To return the value of a number rounded to the nearest integer.


// round value - convert to int64
func Round(value float64) int64 {
if value < 0.0 {
value -= 0.5
} else {
value += 0.5
}
return int64(value)
}
 

--
 
 

Dawid Polak

unread,
Oct 17, 2012, 11:24:45 AM10/17/12
to golan...@googlegroups.com
Johann - but as i wrote before, this code have bug: 

> Float types have limited precisions,  
So I think that function round should behave like fmt.Sprinft( "%.2f", floatNumber ) even if its not correct for smallest numbers. 

ps. I'm put Round and RoundPrec in my small lib for convert and format floats: https://github.com/DeyV/gotools 

-DeyV

Rory McGuire

unread,
Oct 18, 2012, 5:10:08 AM10/18/12
to golan...@googlegroups.com
My bad. The combination of your answer and  Jan's is still the most useful.
Because it is correct for positive and negative values AND it supports multiple precisions. (Only up to float64's precision anyway).

Cheers,

Rory McGuire

unread,
Oct 18, 2012, 5:14:17 AM10/18/12
to golan...@googlegroups.com
@Dawid: Is there a reason you didn't use http://play.golang.org/p/ZmFfr07oHp in your library?

Does your version you chose handle negative numbers correctly now?

Dawid Polak

unread,
Oct 18, 2012, 9:22:30 AM10/18/12
to golan...@googlegroups.com
You are right - this is faster and simpler version - I'm used it now. 

-DeyV

Dan Kortschak

unread,
Oct 18, 2012, 5:19:19 PM10/18/12
to Dawid Polak, golan...@googlegroups.com
But also less correct.

--
 
 

Rory McGuire

unread,
Oct 19, 2012, 4:49:17 AM10/19/12
to golan...@googlegroups.com, Dawid Polak
On Thursday, 18 October 2012 23:19:30 UTC+2, kortschak wrote:
But also less correct.
 
Yes for values bigger than int32's hightest positive value but the float one in that example is wrong for all negative numbers, here is the fixed one:

func RoundViaFloat(x float64, prec int) float64 {
var rounder float64
pow := math.Pow(10, float64(prec))
intermed := x * pow
_, frac := math.Modf(intermed)
x = .5
if frac < 0.0 {
x=-.5
}
if frac >= x {
rounder = math.Ceil(intermed)
} else {
rounder = math.Floor(intermed)
}

return rounder / pow
}

Rory McGuire

unread,
Oct 19, 2012, 4:50:33 AM10/19/12
to golan...@googlegroups.com, Dawid Polak
@Dawid, the RoundViaFloat function is now the most accurate.

Dawid Polak

unread,
Oct 19, 2012, 11:18:07 AM10/19/12
to golan...@googlegroups.com, Dawid Polak
Unfortunately - even in this version is bug: 
Check this: http://play.golang.org/p/S-YiMAcZ2t

I hope that now RoundPrec is correct

-DeyV

Rory McGuire

unread,
Oct 19, 2012, 12:11:12 PM10/19/12
to Dawid Polak, golan...@googlegroups.com

Hope so too.
http://play.golang.org/p/S654PxAe_N fixes the problem for the other function as well.

--
 
 

Joubin Houshyar

unread,
Oct 20, 2012, 9:58:00 PM10/20/12
to golan...@googlegroups.com, Dawid Polak

Christian Espinoza

unread,
Jul 15, 2013, 4:10:51 PM7/15/13
to golan...@googlegroups.com, Dawid Polak
+1 Your Version Work fine to me, Joubin

Brendan Tracey

unread,
Jul 15, 2013, 11:59:14 PM7/15/13
to golan...@googlegroups.com, Dawid Polak
I believe a lot of rounding functions also choose a random rounding direction (or base it off the previous number) if the decimal part is 0.5 exactly

Ian Lance Taylor

unread,
Jul 16, 2013, 12:04:33 AM7/16/13
to Brendan Tracey, golan...@googlegroups.com, Dawid Polak
On Mon, Jul 15, 2013 at 8:59 PM, Brendan Tracey
<tracey....@gmail.com> wrote:
> I believe a lot of rounding functions also choose a random rounding
> direction (or base it off the previous number) if the decimal part is 0.5
> exactly

The most common method for rounding 0.5 is round-half-to-even (i.e.,
least significant bit goes to zero). That is what IEEE 754 specifies,
and that is the floating point format used on all current processors.

Ian

Brendan Tracey

unread,
Jul 16, 2013, 12:07:25 AM7/16/13
to Ian Lance Taylor, golan...@googlegroups.com, Dawid Polak
I stand corrected.

roger peppe

unread,
Jul 16, 2013, 6:40:46 AM7/16/13
to Ian Lance Taylor, Brendan Tracey, golang-nuts, Dawid Polak
It would be nice if that rounding functionality was available
in the standard library (perhaps it is though and I've missed it?)
Reply all
Reply to author
Forward
0 new messages