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

6

我是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

如果有其他方法,请告诉我。 我已经将我的代码插入到Go Playground中。 https://play.golang.org/p/O4n0k0XyMX

这是一个精度误差,但它也取决于你如何格式化输出:https://play.golang.org/p/eFmkI8x3tO - JimB
1
使用math.Modf(),如此回答中所解释的 https://dev59.com/W2Qn5IYBdhLWcg3w1qAc - DeNix
4个回答

4

这是浮点运算的一种特殊情况。由于无法用处理器所采用的浮点格式准确表示所有数字,因此浮点值并不总是完全等于您期望的值。显然,该值非常接近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


1

试试这个:

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

完整答案可在go playground中找到。基本上,我使用格式说明符%g来实现结果,此外,%.6g将小数部分舍入到六位,尾随零不会显示。 fmt包文档

0

-1
在我的情况下,我需要精确的十进制数字,而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

虽然从技术上讲,使用fmt.Sprintf是可行的,但对于这个问题来说,它是低效且过度复杂的。任何人都应该在使用它时进行基准测试,特别是在热路径中使用。 - undefined
请添加解决方案(如果有的话),否则请点赞。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接