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을 참조하십시오 .
Tom 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을 삭제합니까?
데이비드 라슨

3
@DavidLarsen Go 사양 : "부동 소수점 숫자를 정수로 변환 할 때 분수가 삭제됩니다 (0으로 잘림)". ( Go spec )
kvu787 2014

3
이러한 캐스트에는 예상치 못한 Go 문제가 있습니다 (적어도 Java에서 온 경우) : "부동 소수점 또는 복합 값과 관련된 모든 비상 수 변환에서 결과 유형이 값을 나타낼 수없는 경우 변환은 성공하지만 결과는 가치는 구현에 따라 다릅니다. " ( golang.org/ref/spec#Conversions ). 따라서 매우 큰 값을 무한대로 효과적으로 사용하고이를 int로 변환하면 결과가 정의되지 않습니다 (정수 유형의 최대 값인 Java와 달리).
Jaan

12

단순히 int로 캐스팅하면 float가 잘립니다. 시스템이 내부적으로 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.