ChatGPT解决这个技术问题 Extra ChatGPT

在 Go 中将 float64 转换为 int

go

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

int(Round(f)) 将 float64 设置为 int。请参阅stackoverflow.com/a/62753031/12817546float64(i) 将 int 设置为 float64。见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,那么这种转换是否与 Math.Floor(x) 相同,还是因为 float64 将其保存在内存中的方式而放弃了 .7?
@DavidLarsen 来自 Go 规范:“将浮点数转换为整数时,将丢弃分数(截断为零)”。 (Go spec)
这样的强制转换在 Go 中有一个可能出乎意料的问题(至少如果你来自 Java):“在所有涉及浮点或复数值的非常量转换中,如果结果类型不能表示转换成功但结果价值取决于实现。” (golang.org/ref/spec#Conversions)。因此,如果您有效地将一个非常大的值用作无穷大,并将其转换为 int,则结果是未定义的(与 Java 不同,它是整数类型的最大值)。
只是一个更新。看起来 var y = int(x) 对于新的 GO 版本就足够了。
D
David Dooling

简单地转换为 int 会截断浮点数,如果您的系统在内部将 2.0 表示为 1.9999999999,您将不会得到您期望的结果。各种 printf 转换处理此问题并在转换时正确舍入数字。因此,要获得更准确的值,转换比您最初预期的还要复杂:

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

Go Playground 上的代码


s
scaszoo

可能需要正确的舍入。

因此 math.Round() 是您的快速(!)朋友。根据我的测试,使用 fmt.Sprintf 和 strconv.Atois() 的方法慢了 2 个数量级,这些值的矩阵旨在成为正确舍入的 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() 确实返回了一个 float64 值,但之后应用了 int() ,到目前为止我找不到任何不匹配的地方。


P
Peanuts

如果它只是从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)
}

输出:

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

这是操场上的代码 - https://play.golang.org/p/HmFfM6Grqh


Go 有一个 Round 函数,你可以使用它舍入到最接近的整数:math.Round(-64.99) 将输出 -65。
N
Nik

您可以使用 int() 函数将 float64 类型的数据转换为 int。同样,您可以使用 float64()

例子:

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
} 

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

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅