ChatGPT解决这个技术问题 Extra ChatGPT

Convert a float64 to an int in Go

go

How does one convert a float64 to an int in Go? I know the strconv package can be used to convert anything to or from a string, but not between data types where one isn't a string. I know I can use fmt.Sprintf to convert anything to a string, and then strconv it to the data type I need, but this extra conversion seems a bit clumsy - is there a better way to do this?

int(Round(f)) to set a float64 to an int. See stackoverflow.com/a/62753031/12817546. float64(i) to set an int to a float64. See stackoverflow.com/a/62737936/12817546.

D
David Grayson
package main
import "fmt"
func main() {
  var x float64 = 5.7
  var y int = int(x)
  fmt.Println(y)  // outputs "5"
}

@David Grayson, So is this conversion the same as Math.Floor(x) or does it drop the .7 because of the way the float64 saves it in memory?
@DavidLarsen From the Go spec: "When converting a floating-point number to an integer, the fraction is discarded (truncation towards zero)". (Go spec)
Such casts have a problem in Go that can be unexpected (at least if you come from Java): "In all non-constant conversions involving floating-point or complex values, if the result type cannot represent the value the conversion succeeds but the result value is implementation-dependent." (golang.org/ref/spec#Conversions). So if you use a very large value effectively as an infinity, and you convert it into an int, the result is undefined (unlike Java, where it is the maximal value of the integer type).
just an update. looks like var y = int(x) is suffice with new GO version.
D
David Dooling

Simply casting to an int truncates the float, which if your system internally represent 2.0 as 1.9999999999, you will not get what you expect. The various printf conversions deal with this and properly round the number when converting. So to get a more accurate value, the conversion is even more complicated than you might first expect:

package main

import (
    "fmt"
    "strconv"
)

func main() {
    floats := []float64{1.9999, 2.0001, 2.0}
    for _, f := range floats {
        t := int(f)
        s := fmt.Sprintf("%.0f", f)
        if i, err := strconv.Atoi(s); err == nil {
            fmt.Println(f, t, i)
        } else {
            fmt.Println(f, t, err)
        }
    }
}

Code on Go Playground


s
scaszoo

Correct rounding is likely desired.

Therefore math.Round() is your quick(!) friend. Approaches with fmt.Sprintf and strconv.Atois() were 2 orders of magnitude slower according to my tests with a matrix of float64 values that were intended to become correctly rounded int values.

package main
import (
    "fmt"
    "math"
)
func main() {
    var x float64 = 5.51
    var y float64 = 5.50
    var z float64 = 5.49
    fmt.Println(int(math.Round(x)))  // outputs "6"
    fmt.Println(int(math.Round(y)))  // outputs "6"
    fmt.Println(int(math.Round(z)))  // outputs "5"
}

math.Round() does return a float64 value but with int() applied afterwards, I couldn't find any mismatches so far.


P
Peanuts

If its simply from float64 to int, this should work

package main

import (
    "fmt"
)

func main() {
    nf := []float64{-1.9999, -2.0001, -2.0, 0, 1.9999, 2.0001, 2.0}

    //round
    fmt.Printf("Round : ")
    for _, f := range nf {
        fmt.Printf("%d ", round(f))
    }
    fmt.Printf("\n")

    //rounddown ie. math.floor
    fmt.Printf("RoundD: ")
    for _, f := range nf {
        fmt.Printf("%d ", roundD(f))
    }
    fmt.Printf("\n")

    //roundup ie. math.ceil
    fmt.Printf("RoundU: ")
    for _, f := range nf {
        fmt.Printf("%d ", roundU(f)) 
    }
    fmt.Printf("\n")

}

func roundU(val float64) int {
    if val > 0 { return int(val+1.0) }
    return int(val)
}

func roundD(val float64) int {
    if val < 0 { return int(val-1.0) }
    return int(val)
}

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

Outputs:

Round : -2 -2 -2 0 2 2 2 
RoundD: -2 -3 -3 0 1 2 2 
RoundU: -1 -2 -2 0 2 3 3 

Here's the code in the playground - https://play.golang.org/p/HmFfM6Grqh


Go has a Round function you can use that rounds to the nearest integer: math.Round(-64.99) will output -65.
N
Nik

You can use int() function to convert float64 type data to an int. Similarly you can use float64()

Example:

func check(n int) bool { 
    // count the number of digits 
    var l int = countDigit(n)
    var dup int = n 
    var sum int = 0 

    // calculates the sum of digits 
    // raised to power 
    for dup > 0 { 
        **sum += int(math.Pow(float64(dup % 10), float64(l)))** 
        dup /= 10 
    } 

    return n == sum
} 

关注公众号,不定期副业成功案例分享
Follow WeChat

Success story sharing

Want to stay one step ahead of the latest teleworks?

Subscribe Now