浮点数不能全等比较吗php,golang比较浮点数是否相等

由于小数二进制和十进制转换的时候,会有精度丢失的问题,所以我们在比较浮点数是否相等,指的是在一定精度范围内的两个浮点数是否相等。

参看了网上其他人的实现

实现1,实现2

基本上都一样,于是我就改了几个值验证了一下,

结果发下

package main

import (

"fmt"

"math"

)

const MIN = 0.000001

// MIN 为用户自定义的比较精度

func IsEqual(f1, f2 float64) bool {

return math.Dim(f1, f2) < MIN

}

func main() {

a := 0.9

b := 1.0

if IsEqual(a, b) {

fmt.Println("a==b")

}else{

fmt.Println("a!=b")

}

}

这两个数相差为0.1 ,大于可以认为相等的精度,应该输出是a!=b,,但是很神奇,这个程序输出的结果是a==b,而且这个程序被多个网站转载。

那么这个程序一定是有什么地方没有考虑到。

这是一个逻辑很简单的程序,不知道当初写这个程序的人为什么要使用math.Dim,看起来高大上,百度了一下,前两条给的说明是:https://my.oschina.net/u/3625745/blog/3062717,https://www.lmlphp.com/user/2043/article/item/342102/含义“复数的维度”。老实说没有看懂。按照浮点数的原理,这里equal功能只是,比较一下大小,两者相差(不关心正负,需要取绝对值),小于可以接受的精度,即可认为相等

package main

import "fmt"

const MIN = 0.000001

// MIN 为用户自定义的比较精度

func IsEqual(f1, f2 float64) bool {

if f1>f2 {

return f1-f2< MIN

}else{

return f2-f1

}

}

func main() {

a := 0.9

b := 1.0

if IsEqual(a, b) {

fmt.Println("a == b")

}else{

fmt.Println("a!=b")

}

}

这样输出的结果就对了,顺便也测试了精度小于0.000001的两个数直接判断相等了。

那么原来的程序错在什么地方呢?

查看看一下math.Dim的文档," Dim() function provided by the math package return the maximum of a-b or 0. "

也就是这个函数比较第一个参数和第二个参数的差值,然后和0比较大小。我们这里需要精度是两个参数的差的绝对值,不关注正负。

package main

import (

"fmt"

"math"

)

const MIN = 0.000001

// MIN 为用户自定义的比较精度

func IsEqual(f1, f2 float64) bool {

if f1>f2{

return math.Dim(f1, f2) < MIN

}else{

return math.Dim(f2, f1) < MIN

}

}

func main() {

a := 0.9

b := 1.0

if IsEqual(a, b) {

fmt.Println("a==b")

}else{

fmt.Println("a!=b")

}

}

这样运算结果就对了。但是这样多引入了math包,实际程序也没有变得简单。所以写程序还是应该追求简单实用,不要为了高大上而复杂。

有疑问加站长微信联系(非本文作者)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值