简体   繁体   English

在 Go 中将 float64 转换为 int

[英]Convert a float64 to an int in Go

How does one convert a float64 to an int in Go?在 Go 中如何将 float64 转换为 int? 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.我知道strconv包可用于将任何内容转换为字符串或从字符串转换任何内容,但不能在不是字符串的数据类型之间进行转换。 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?我知道我可以使用fmt.Sprintf将任何内容转换为字符串,然后strconv其转换为我需要的数据类型,但是这种额外的转换似乎有点笨拙 - 有没有更好的方法来做到这一点?

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

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.简单地转换为 int 会截断浮点数,如果您的系统内部将 2.0 表示为 1.9999999999,您将不会得到您期望的结果。 The various printf conversions deal with this and properly round the number when converting.各种 printf 转换处理这个问题,并在转换时正确地舍入数字。 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代码操场

Correct rounding is likely desired.可能需要正确的舍入。

Therefore math.Round() is your quick(!) friend.因此 math.Round() 是您的快速(!)朋友。 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.根据我的测试,使用 fmt.Sprintf 和 strconv.Atois() 的方法要慢 2 个数量级,其中 float64 值的矩阵旨在成为正确舍入的 int 值。

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. math.Round() 确实返回了一个 float64 值,但是在之后应用了 int() 之后,到目前为止我找不到任何不匹配的地方。

If its simply from float64 to int, this should work如果它只是从 float64 到 int,这应该可以工作

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这是操场上的代码 - https://play.golang.org/p/HmFfM6Grqh

You can use int() function to convert float64 type data to an int .您可以使用int()函数将float64类型的数据转换为int Similarly you can use float64()同样,您可以使用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
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM