Ubah float64 menjadi int di Go

124

Bagaimana cara mengubah float64 menjadi int di Go? Saya tahu strconvpaket tersebut dapat digunakan untuk mengonversi apa pun ke atau dari string, tetapi tidak di antara tipe data di mana satu bukan string. Saya tahu saya dapat menggunakan fmt.Sprintfuntuk mengonversi apa pun menjadi string, dan kemudian strconvke tipe data yang saya butuhkan, tetapi konversi tambahan ini tampaknya agak kikuk - adakah cara yang lebih baik untuk melakukan ini?

Chris Bunch
sumber
int(Round(f))untuk mengatur float64 ke int. Lihat stackoverflow.com/a/62753031/12817546 . float64(i)untuk menyetel int ke float64. Lihat stackoverflow.com/a/62737936/12817546 .
Tom J

Jawaban:

202
package main
import "fmt"
func main() {
  var x float64 = 5.7
  var y int = int(x)
  fmt.Println(y)  // outputs "5"
}
David Grayson
sumber
1
@ David Grayson, Jadi, apakah konversi ini sama dengan Math.Floor (x) atau apakah itu menjatuhkan 0,7 karena cara float64 menyimpannya dalam memori?
David Larsen
3
@DavidLarsen Dari spesifikasi Go: "Saat mengonversi bilangan floating-point menjadi integer, pecahan akan dibuang (pemotongan menuju nol)". ( Pergi spesifikasi )
kvu787
3
Pemeran tersebut memiliki masalah di Go yang mungkin tidak terduga (setidaknya jika Anda berasal dari Java): "Dalam semua konversi non-konstan yang melibatkan nilai titik-mengambang atau kompleks, jika jenis hasil tidak dapat mewakili nilai, konversi berhasil tetapi hasilnya nilai bergantung pada implementasi. " ( golang.org/ref/spec#Conversions ). Jadi jika Anda menggunakan nilai yang sangat besar secara efektif sebagai infinity, dan Anda mengubahnya menjadi int, hasilnya tidak terdefinisi (tidak seperti Java, yang merupakan nilai maksimal dari tipe integer).
Jaan
12

Cukup mentransmisikan ke int memotong float, yang jika sistem Anda secara internal merepresentasikan 2.0 sebagai 1.9999999999, Anda tidak akan mendapatkan apa yang Anda harapkan. Berbagai konversi printf menangani ini dan membulatkan angka dengan benar saat mengonversi. Jadi, untuk mendapatkan nilai yang lebih akurat, konversi menjadi lebih rumit dari yang Anda perkirakan sebelumnya:

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

Kode di Go Playground

David Dooling
sumber
8

Jika hanya dari float64 ke int, ini seharusnya berfungsi

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

Keluaran:

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

Berikut kode di taman bermain - https://play.golang.org/p/HmFfM6Grqh

Kacang kacangan
sumber
Go memiliki fungsi Round Anda dapat menggunakan putaran tersebut ke bilangan bulat terdekat: math.Round (-64,99) akan menghasilkan -65.
Honarmand
2

Anda dapat menggunakan int()fungsi untuk mengubah float64tipe data menjadi file int. Demikian pula yang bisa Anda gunakanfloat64()

Contoh:

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
} 
Pembuat kode
sumber
2

Pembulatan yang benar mungkin diinginkan.

Oleh karena itu, math.Round () adalah teman cepat (!) Anda. Pendekatan dengan fmt.Sprintf dan strconv.Atois () adalah 2 kali lipat lebih lambat menurut pengujian saya dengan matriks nilai float64 yang dimaksudkan untuk menjadi nilai int yang dibulatkan dengan benar.

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 () mengembalikan nilai float64 tetapi dengan int () diterapkan setelahnya, sejauh ini saya tidak dapat menemukan ketidakcocokan.

scaszoo
sumber