How can we truncate float64 type to a particular precision?

前端 未结 12 1421
礼貌的吻别
礼貌的吻别 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:08

    The answer by threeve brought me to this issue on GitHub where a solution based on math/big for rounding values is presented - this way the rounding method is used correctly:

    package main
    
    import (
        "fmt"
        "math/big"
    )
    
    func main() {
        f := new(big.Float).SetMode(big.ToNearestEven).SetFloat64(10/3.0)
        // Round to 2 digits using formatting.
        f.SetPrec(8)
        fmt.Printf("%.2f\n", f)
    }
    

    The rounding mode is also respected in threeve's example:

    j := 0.045
    
    f := new(big.Float).SetMode(big.AwayFromZero).SetFloat64(j)
    // Round to 2 digits using formatting.
    f.SetPrec(8)
    fmt.Printf("%.2f\n", f)
    

    -> correctly yields 0.05

    Also, Go 1.10 has been released and added a math.Round() function, see this excellent answer by icza: Golang Round to Nearest 0.05

    package main
    
    import (
        "fmt"
        "math"
    )
    
    func main() {
    
        fmt.Println(Round(10/3.0, 0.01))
    
    }
    
    func Round(x, unit float64) float64 {
        return math.Round(x/unit) * unit
    }
    

    However, one should not use float for storing monetary values. (See: Why not use Double or Float to represent currency?) One way around this is using a library that implements decimal like https://github.com/ericlagergren/decimal or https://github.com/shopspring/decimal

提交回复
热议问题