golang 处理浮点数的疑问

2022-11-12 19:19:08 +08:00
 echooo0

由于浮点数和整数直接相乘,有丢失精度的问题,查了查资料用了第三方的库 github.com/shopspring/decimal

num2 := 512  
num1 := 2.7

d, _ := decimal.NewFromFloat(num1).Mul(decimal.NewFromInt(int64(num2))).Float64()  
fmt.Printf("d = %f", d)

测试计算结果是 1382.400024 ,好像也不是准确的数字啊?

update: 好像从数据库取出来的 num1(float 类型)就不精确,难道要用 string 来存储比较好么。。。。

1986 次点击
所在节点    Go 编程语言
14 条回复
Trim21
2022-11-12 19:23:47 +08:00
decimal.NewFromFloat(num1).Mul(decimal.NewFromInt(int64(num2))).String() ?这样结果倒是精确的
Trim21
2022-11-12 19:25:19 +08:00
而且 Float64 有第二个返回值告诉你结果准确不准确,你直接给忽略掉了...
echooo0
2022-11-12 19:29:40 +08:00
@Trim21 #2 那个返回值没啥用啊,我要的就是精确的值。。。。
echooo0
2022-11-12 19:30:30 +08:00
@Trim21 #1 从数据库读取出来的 num1 (用 float 类型接收的)就有问题,不是 2.7 ,是 2.700001
echooo0
2022-11-12 19:35:35 +08:00
貌似解决了,小数得用 string 来存数据库。。。。
TWorldIsNButThis
2022-11-12 19:39:44 +08:00
数据库不是也有 decimal 么
echooo0
2022-11-12 19:48:09 +08:00
@TWorldIsNButThis #6 go 目前官方没有 decimal 类型吧,得依靠第三方的库去转换
GTim
2022-11-12 21:43:44 +08:00
https://www.twle.cn/t/90550#reply0 我刚写的,目前最好用的就这个了
0987363
2022-11-13 09:20:28 +08:00
用 float64 直接乘也没见有问题
echooo0
2022-11-13 09:47:33 +08:00
@0987363 #9 我的例子给的有点问题,num1 输入的值就有问题,实际上不是 2.7 ,而是 2.700001 ,所以造成最后相乘的结果有误差。num1 是从数据库读取的浮点类型,估计是有误差的,目前通用的做法应该是设置成 decimal 类型,至少也得是个 string 类型....
echooo0
2022-11-13 09:48:49 +08:00
@echooo0 #10 浮点类型用于一般的科学运算没问题,但是要是金融,或者反复运算的场景,误差就比较大了
lysS
2022-11-13 11:07:33 +08:00
官方库不是有 big 嘛? math/big/#Float.Mul 。float 数据库存字符串就行。基础类型的 float 只能表示 16 位精度
lysS
2022-11-13 11:10:20 +08:00
就你列的那两个数,用基础类型是足以应付的
IIIlllIIllIIIll
2022-12-03 11:15:00 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/894739

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX