Goでfloat64をintに変換する


124

Goでfloat64をintに変換するにはどうすればよいですか?このstrconvパッケージを使用して、何かを文字列に、または文字列から変換できますが、文字列でないデータ型の間ではできません。fmt.Sprintf何かを文字列に変換してからstrconv必要なデータ型に変換できることはわかっていますが、この余分な変換は少し扱いに​​くいようです-これを行うためのより良い方法はありますか?


int(Round(f))float64をintに設定します。stackoverflow.com/a/62753031/12817546を参照してください。float64(i)intをfloat64に設定します。stackoverflow.com/a/62737936/12817546を参照してください。
トムJ

回答:


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

1
@David Grayson、それでこの変換はMath.Floor(x)と同じですか、それともfloat64がメモリに保存する方法のために.7をドロップしますか?
David Larsen

3
@DavidLarsen Go仕様から:「浮動小数点数を整数に変換すると、小数部は破棄されます(ゼロへの切り捨て)」。(スペックを行く
kvu787 14年

3
このようなキャストには、Goで予期しない問題が発生する可能性があります(少なくともJavaからの場合)。値は実装に依存します。」(golang.org/ref/spec#Conversions)。したがって、非常に大きな値を無限大として効果的に使用し、それをintに変換すると、結果は未定義になります(Javaとは異なり、整数型の最大値です)。
Jaan、2016年

12

単に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のコード


8

単に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を出力します。
AHonarmand

2

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
} 

2

正しい丸めが望ましいと思われます。

したがって、math.Round()はあなたのクイック(!)フレンドです。fmt.Sprintfとstrconv.Atois()を使用したアプローチは、正しく丸められたint値になるように意図されたfloat64値の行列を使用したテストによると、2桁遅くなりました。

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()を適用すると、これまでのところ不一致を見つけることができませんでした。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.