You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Go与Python执行大数除法时返回结果不同?

为何Go与Python在执行大数除法时返回结果不同?

代码与输出对比

Go语言实现

package main

import (
	"fmt"
	"math/big"
)

func main() {
	x, y := big.NewFloat(26959535291011309493156476344723991336010898738574164086137773096960), big.NewFloat(14484.162361)
	z := new(big.Float).Quo(x, y)
	fmt.Println(fmt.Sprintf("%f", z))
}

输出:1861311315012765262390495455137379355146730679910059382988079104.000000

Python实现

v1 = 26959535291011309493156476344723991336010898738574164086137773096960000000
v2 = 14484162361
print(v1 / v2)

输出:1861311315012765306929610463010191006516769515973403833769533170

核心差异原因

两者结果不同的本质是计算时的精度模型和数值表示方式完全不同:

1. Go的big.Float存在精度损耗

  • 你用big.NewFloat(14484.162361)初始化除数时,这个十进制小数首先会被转成float64类型存储。但float64是双精度浮点数,无法精确表示所有十进制小数——14484.162361的二进制是无限循环的,只能被近似存储,这就引入了初始误差。
  • 后续的除法运算中,big.Float默认继承了float64的64位精度,这个微小的初始误差会随着超大数运算被不断放大,最终导致结果和精确值出现明显偏差。

2. Python的任意精度整数运算无损耗

  • 你在Python中使用的v1和v2都是任意精度整数,Python对整数的大小没有限制,能精确存储和计算这些超大数值。
  • 虽然你用了/运算符,但因为v1恰好是v2的整数倍,Python内部会直接返回精确的整数结果(如果结果不是整数,/会返回精度有限的float,但这个场景下不存在这个问题)。

让Go得到精确结果的解决方案

要在Go中得到和Python一致的精确结果,建议改用整数运算完全规避浮点数的精度问题:

package main

import (
	"fmt"
	"math/big"
)

func main() {
	// 用字符串初始化超大整数,避免float64的精度损失
	x := new(big.Int)
	x.SetString("26959535291011309493156476344723991336010898738574164086137773096960", 10)
	// 将原除法转为整数运算:x/14484.162361 = (x*100000000)/14484162361
	x.Mul(x, big.NewInt(100000000))
	y := big.NewInt(14484162361)
	z := new(big.Int).Div(x, y)
	fmt.Println(z)
}

这段代码会输出和Python完全一致的精确结果,因为全程使用整数运算,没有任何近似误差。


内容的提问来源于stack exchange,提问作者user3675730

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:41:58