MST

星途 面试题库

面试题:Go语言类型转换中的潜在精度丢失风险

在Go语言中,当进行从float64到int类型的转换时,会面临精度丢失的问题。请编写一段代码,展示这种精度丢失的情况,并解释为何会发生精度丢失,同时说明如何在实际编程中尽量避免因这种类型转换导致的精度问题。
39.3万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

代码展示精度丢失

package main

import (
    "fmt"
)

func main() {
    num := 1.999999999999999999
    intNum := int(num)
    fmt.Printf("原始浮点数: %f\n", num)
    fmt.Printf("转换后的整数: %d\n", intNum)
}

精度丢失原因

  1. 浮点数存储原理
    • float64在Go语言中遵循IEEE 754标准,它使用64位来表示一个浮点数,其中1位符号位,11位指数位,52位尾数位。
    • 例如1.999999999999999999这样的数,在浮点数表示中无法精确存储,它在内存中的实际存储值可能与真实值略有偏差。
  2. 转换过程
    • 当从float64转换为int时,Go语言会直接截断小数部分,只保留整数部分。所以1.999999999999999999转换为int后就是1,导致精度丢失。

避免精度问题的方法

  1. 四舍五入
    • 使用math.Round函数实现四舍五入后再转换。例如:
package main

import (
    "fmt"
    "math"
)

func main() {
    num := 1.999999999999999999
    rounded := math.Round(num)
    intNum := int(rounded)
    fmt.Printf("原始浮点数: %f\n", num)
    fmt.Printf("四舍五入后转换的整数: %d\n", intNum)
}
  1. 设置精度阈值
    • 如果业务允许一定的误差范围,可以设置一个精度阈值。例如,当浮点数减去其整数部分小于某个阈值(如0.0001)时,可认为其小数部分可忽略不计,直接转换为整数。
package main

import (
    "fmt"
)

func main() {
    num := 1.999999999999999999
    threshold := 0.0001
    intPart := int(num)
    if num - float64(intPart) < threshold {
        intNum := int(num)
        fmt.Printf("原始浮点数: %f\n", num)
        fmt.Printf("按阈值转换的整数: %d\n", intNum)
    }
}