How to round to nearest int when casting float to int in go
Asked Answered
A

2

13

When casting float to int the decimal is discarded. What's a clean way to cast so that it rounds to the nearest whole number instead.

x := int(3.6) should equal 4 instead of 3.

Agace answered 31/1, 2016 at 15:59 Comment(5)
Possible duplicate of Go: Converting float64 to int with multiplierMcdonald
Related issue: math: add a Round functionIrascible
@Akavall edited title,Agace
int(Round(f)) to round a float to an int. See https://mcmap.net/q/56303/-how-to-round-to-nearest-int-when-casting-float-to-int-in-go. float64(i) to set an int to a float. See https://mcmap.net/q/55267/-idiomatic-type-conversion-in-go.Dasha
Has this changed? See go.dev/play/p/tEKYVunbNd_x.Gracious
A
11

int(f+0.5) will cause upwards rounding if it's >= .5

This only works well for low precision rounding. E.g.

var f1 = 6.499999999999999
var f2 = 6.4999999999999999
var i1 = int(f1+0.5) // equals 6
var i2 = int(f2+0.5) // equals 7

This can cause non-deterministic behavior. See answer below w/ math.round for a better solution.

Agace answered 31/1, 2016 at 15:59 Comment(2)
This provides a type conversion; please note that the term cast is not used.Origami
Also, your type conversion will not work well with negative numbers if you intended the rounding to be to the nearest whole integer.Origami
D
11

You could use int(math.Round(f)) to round to the nearest whole number when converting a float to an int in Go. The decimal is also discarded when a float is set to a byte or a rune. Truncation doesn't happen when it's set to a string or a bool.

package main

import (
  . "fmt"
  . "math"
)

func main() {
  f := 3.6
  c := []interface{}{byte(f), f, int(Round(f)), rune(f), Sprintf("%.f", f), f != 0}
  checkType(c)
}
func checkType(s []interface{}) {
  for k, _ := range s {
     Printf("%T %v\n", s[k], s[k])
  }
}

Round returns the nearest integer, rounding half away from zero. See https://golang.org/pkg/math/#Round. See https://mcmap.net/q/56920/-convert-a-float64-to-an-int-in-go.

f := 3.6 truncates to “uint8 3”, f is “float64 3.6”, int(Round(f)) rounds up to “int 4”, rune(f) truncates to “int32 3”, Sprintf("%.f", f) is “string 3.6” and f != 0 outputs “bool true”.

Dasha answered 6/7, 2020 at 9:24 Comment(1)

© 2022 - 2024 — McMap. All rights reserved.