英文:
Convert a float64 to an int in Go
问题
如何在Go中将float64转换为int?我知道strconv
包可以用于将任何东西转换为字符串或从字符串转换,但不能在一个不是字符串的数据类型之间转换。我知道我可以使用fmt.Sprintf
将任何东西转换为字符串,然后使用strconv
将其转换为我需要的数据类型,但这种额外的转换似乎有点笨拙 - 有没有更好的方法来做到这一点?
英文:
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?
答案1
得分: 313
package main
import "fmt"
func main() {
var x float64 = 5.7
var y int = int(x)
fmt.Println(y) // 输出 "5"
}
英文:
package main
import "fmt"
func main() {
var x float64 = 5.7
var y int = int(x)
fmt.Println(y) // outputs "5"
}
答案2
得分: 19
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
英文:
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
答案3
得分: 17
正确的四舍五入可能是需要的。
因此,math.Round() 是你快速的朋友。
根据我的测试,使用 fmt.Sprintf 和 strconv.Atoi() 的方法要慢两个数量级,这些测试是针对一个包含 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))) // 输出 "6"
fmt.Println(int(math.Round(y))) // 输出 "6"
fmt.Println(int(math.Round(z))) // 输出 "5"
}
math.Round() 返回一个 float64 值,但在之后应用 int(),我目前找不到任何不匹配的情况。
<details>
<summary>英文:</summary>
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.
</details>
# 答案4
**得分**: 6
如果只是从float64转换为int,这应该可以工作。
```go
package main
import (
"fmt"
)
func main() {
nf := []float64{-1.9999, -2.0001, -2.0, 0, 1.9999, 2.0001, 2.0}
//四舍五入
fmt.Printf("Round : ")
for _, f := range nf {
fmt.Printf("%d ", round(f))
}
fmt.Printf("\n")
//向下取整,即math.floor
fmt.Printf("RoundD: ")
for _, f := range nf {
fmt.Printf("%d ", roundD(f))
}
fmt.Printf("\n")
//向上取整,即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
这是在playground中的代码 - https://play.golang.org/p/HmFfM6Grqh
英文:
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
答案5
得分: 4
你可以使用int()
函数将float64
类型的数据转换为int
类型。同样,你也可以使用float64()
函数。
示例:
func check(n int) bool {
// 计算数字的位数
var l int = countDigit(n)
var dup int = n
var sum int = 0
// 计算数字的位数的幂的和
for dup > 0 {
**sum += int(math.Pow(float64(dup % 10), float64(l)))**
dup /= 10
}
return n == sum
}
英文:
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
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论