How can we truncate float64 type to a particular precision?

前端 未结 12 1412
礼貌的吻别
礼貌的吻别 2021-02-02 05:33
package main

import (
    \"fmt\"
    \"strconv\"
    )

func main() {
    k := 10/3.0
    i := fmt.Sprintf(\"%.2f\", k)
    f,_ := strconv.ParseFloat(i, 2)
    fmt.Pri         


        
相关标签:
12条回答
  • 2021-02-02 06:12

    You don't need any extra code ... its as simple as

    import (
        "fmt"
    )
    
    func main() {
        k := 10 / 3.0
        fmt.Printf("%.2f", k)
    }
    

    Test Code

    0 讨论(0)
  • 2021-02-02 06:15

    The following code should work for a lot of simple use cases with relatively small numbers and small precision inputs. However, it may not work for some uses cases because of numbers overflowing out of the range of float64 numbers, as well as IEEE-754 rounding errors (other languages have this issue as well).

    If you care about using larger numbers or need more precision, the following code may not work for your needs, and you should use a helper library (e.g. https://github.com/shopspring/decimal).

    I picked up a one-liner round function from elsewhere, and also made toFixed() which depends on round():

    func round(num float64) int {
        return int(num + math.Copysign(0.5, num))
    }
    
    func toFixed(num float64, precision int) float64 {
        output := math.Pow(10, float64(precision))
        return float64(round(num * output)) / output
    }
    

    Usage:

    fmt.Println(toFixed(1.2345678, 0))  // 1
    fmt.Println(toFixed(1.2345678, 1))  // 1.2
    fmt.Println(toFixed(1.2345678, 2))  // 1.23
    fmt.Println(toFixed(1.2345678, 3))  // 1.235 (rounded up)
    
    0 讨论(0)
  • 2021-02-02 06:15

    This is a little workaround how can you round float using type conversion to int back and forth:

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        k := 10 / 3.0
        k = float64(int(k*100)) / 100
        fmt.Println(k)  // output 3.33
    }
    

    https://play.golang.org/p/yg2QYcZ-2u

    0 讨论(0)
  • 2021-02-02 06:19

    Functions without checking for large floats

    // Rounds like 12.3416 -> 12.35
    func RoundUp(val float64, precision int) float64 {
        return math.Ceil(val*(math.Pow10(precision))) / math.Pow10(precision)
    }
    
    // Rounds like 12.3496 -> 12.34
    func RoundDown(val float64, precision int) float64 {
        return math.Floor(val*(math.Pow10(precision))) / math.Pow10(precision)
    }
    
    // Rounds to nearest like 12.3456 -> 12.35
    func Round(val float64, precision int) float64 {
        return math.Round(val*(math.Pow10(precision))) / math.Pow10(precision)
    }
    
    0 讨论(0)
  • 2021-02-02 06:20

    So after much hunting around, coming to this thread multiple times I finally found a very simple solution that allows you to control the precision of floats very simply without any weird math!

    package main
    
    import (
        "fmt"
        "github.com/shopspring/decimal"
    )
    
    func main() {
        k := 101.3874927181298723478
        p := 5
    
        v := decimal.NewFromFloat(k).Round(int32(p))
        fmt.Println(v)
    }
    // 101.38749
    

    Source: https://godoc.org/github.com/shopspring/decimal#Decimal.Round

    While I like some of the simple methods like "%.3f\n", k options, these produced a string that I would then have to convert back into a float with another strconv command that I didn't want to do.

    0 讨论(0)
  • 2021-02-02 06:22

    Be careful with longitude and latitude float as truncating and rounding can yield completely different results... as it can put you on the wrong side of a latitude boundary.

    0 讨论(0)
提交回复
热议问题