使用golang分隔整数部分和小数部分

dgiusagp  于 2023-01-06  发布在  Go
关注(0)|答案(4)|浏览(276)

我是Golang的新手。我想把一个浮点数分成整数和小数部分。经过一些研究,我实现了它,但我的代码有一个问题。我使用5.8作为输入,但结果是5和0.79999。

package main

import(
        "fmt"
        "math"
)    

func Round2(val float64) {
        intpart, div := math.Modf(val)
        fmt.Println(div)

        fmt.Println(intpart)

}

func main() {
        fmt.Println("Hello, playground")
        Round2(5.8)
}

我试过了,我得到的输出是:

0.7999999999999998
5

如果有任何其他的方法来做到这一点,请让我知道。我已经插入了我的代码去操场在它。
https://play.golang.org/p/O4n0k0XyMX

z9ju0rcb

z9ju0rcb1#

这是浮点运算的产物。浮点值并不总是你所期望的值,因为不是所有的数字都能用你所使用的浮点格式来表示。显然,这个值非常接近0.8,等于15位有效数字。注意,这并不是Go语言特有的。
代替

fmt.Println(div)

尝试

fmt.Printf(".4f\n", div) // shows only 4 decimal places

看起来这篇文章有一些很好的信息:https://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

dohp0rv5

dohp0rv52#

试试这个:

f := 5.8
ipart := int64(f)
fmt.Println(ipart)
decpart := fmt.Sprintf("%.7g", f-float64(ipart))[2:]
fmt.Println(decpart)

完整的答案在go playground中,基本上我使用了格式说明符%g来获得结果,此外,%.6g将小数部分四舍五入到六位,尾部零没有显示。
Documentation of fmt package

tv6aics1

tv6aics13#

您可能希望使用精度固定为.00的Decimal64p2类型的小数-https://github.com/strongo/decimal
它能有效地存储准确的钱数。

brvekthn

brvekthn4#

在我的例子中,我需要***精确的***小数位数,而Modf需要改变一些数字,所以我创建了一个如下的效用函数:

func getIntDecimal(val float64) (int64, float64, error) {
  decimalPart := 0.00
  s := fmt.Sprintf("%v", val)
  split := strings.Split(s, ".")
  decimalStr := "0." + split[1]
  decimalPart, err := strconv.ParseFloat(decimalStr, 4)
  intPart, err := strconv.ParseInt(split[0], 10, 0)
  fmt.Println(intPart, decimalPart)
  return intPart, decimalPart, err
}

在主函数中这样使用它:

v := 252.4569
i, d, err := getIntDecimal(v)
if err != nil {
    log.Printf("Error %s in converting value to int and decimal", err)
}
fmt.Println(i, f)

输出结果为:

252 0.4569

相关问题