将float64转换为int在Go中

huangapple go评论74阅读模式
英文:

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 (
        &quot;fmt&quot;
        &quot;math&quot;
    )
    func main() {
        var x float64 = 5.51
        var y float64 = 5.50
        var z float64 = 5.49
        fmt.Println(int(math.Round(x)))  // outputs &quot;6&quot;
        fmt.Println(int(math.Round(y)))  // outputs &quot;6&quot;
        fmt.Println(int(math.Round(z)))  // outputs &quot;5&quot;
    }

math.Round() does return a float64 value but with int() applied afterwards, I couldn&#39;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 (
&quot;fmt&quot;
)
func main() {
nf := []float64{-1.9999, -2.0001, -2.0, 0, 1.9999, 2.0001, 2.0}
//round
fmt.Printf(&quot;Round : &quot;)
for _, f := range nf {
fmt.Printf(&quot;%d &quot;, round(f))
}
fmt.Printf(&quot;\n&quot;)
//rounddown ie. math.floor
fmt.Printf(&quot;RoundD: &quot;)
for _, f := range nf {
fmt.Printf(&quot;%d &quot;, roundD(f))
}
fmt.Printf(&quot;\n&quot;)
//roundup ie. math.ceil
fmt.Printf(&quot;RoundU: &quot;)
for _, f := range nf {
fmt.Printf(&quot;%d &quot;, roundU(f)) 
}
fmt.Printf(&quot;\n&quot;)
}
func roundU(val float64) int {
if val &gt; 0 { return int(val+1.0) }
return int(val)
}
func roundD(val float64) int {
if val &lt; 0 { return int(val-1.0) }
return int(val)
}
func round(val float64) int {
if val &lt; 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 &gt; 0 { 
**sum += int(math.Pow(float64(dup % 10), float64(l)))** 
dup /= 10 
} 
return n == sum
} 

huangapple
  • 本文由 发表于 2011年11月6日 02:43:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/8022389.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定