Golang浮点数比较和运算会出现误差。
浮点数储存至内存中时,2的-1、-2……-n次方不能精确的表示小数部分,所以再把这个数从地址中取出来进行计算就出现了偏差。
package main
import (
"errors"
"fmt"
"github.com/shopspring/decimal"
)
func FloatCompare(f1, f2 interface{}) (n int, err error) {
var f1Dec, f2Dec decimal.Decimal
switch f1.(type) {
case float64:
f1Dec = decimal.NewFromFloat(f1.(float64))
switch f2.(type) {
case float64:
f2Dec = decimal.NewFromFloat(f2.(float64))
case string:
f2Dec, err = decimal.NewFromString(f2.(string))
if err != nil {
return 2, err
}
default:
return 2, errors.New("FloatCompare() expecting to receive float64 or string")
}
case string:
f1Dec, err = decimal.NewFromString(f1.(string))
if err != nil {
return 2, err
}
switch f2.(type) {
case float64:
f2Dec = decimal.NewFromFloat(f2.(float64))
case string:
f2Dec, err = decimal.NewFromString(f2.(string))
if err != nil {
return 2, err
}
default:
return 2, errors.New("FloatCompare() expecting to receive float64 or string")
}
default:
return 2, errors.New("FloatCompare() expecting to receive float64 or string")
}
return f1Dec.Cmp(f2Dec), nil
}
func main() {
a:=4.0
b:="4"
fmt.Println(FloatCompare(a,b))
}
补充:golang 判断2个浮点型数字是否相同
判断2个浮点型数字是否相同的方法(假定整数部分+小数点后3位相同,则视为相同)
首先将2个浮点型数字转换为string数据
将float类型的数据转换成string
func Decimal(value float32) string {
value1 := fmt.Sprintf("%.6f", value)
return value1
}
比较两个由float型数据转化成string的数据是否相同是否相同
func Compare(val1,val2 string) bool {
indexf :=strings.Index(val1,".") + 4
indexs :=strings.Index(val2,".") + 4
if indexs != indexf {
return false
}else {
if val1[0:indexf] == val2[0:indexs]{
return true
}else {
return false
}
}
}
补充:golang 浮点数操作
数据库中金额元存储的数据结构使用的是decimal(15,2),golang中使用float64保存变量内容。通过转换将 float64 -> int64
最简单的方式:int64(float64 * 100),但是由于浮点数在计算机内的表示方式问题导致有一部分数据会出现问题,
例如:
var v = 67.6
fmt.Println(int64(v *100)) 输出结果为:6759
解决方法:
使用"github.com/shopspring/decimal"包,将对浮点数进行精确计算,例如:
f1 := decimal.NewFromFloat(v)
f2 := decimal.NewFromFloat(100)
fmt.Println(f1.Mul(f2).IntPart()) 输出结果为6760
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。
您可能感兴趣的文章:- golang实现对docker容器心跳监控功能
- 浅谈golang 中time.After释放的问题
- golang 定时任务方面time.Sleep和time.Tick的优劣对比分析
- golang日志包logger的用法详解
- golang elasticsearch Client的使用详解
- Golang的func参数及返回值操作
- golang协程池模拟实现群发邮件功能
- Golang: 内建容器的用法