前段时间在开发微信支付和支付宝支付时碰到了这么一个问题,在比较数据时看着是一样的,结果怎么都是不一样的,现在把产生的原因记录一下。
备注:下面的文章是转载的,已经可以很好的说明此问题了。
浮点数(floats)
die(var_dump(1200.85 * 100 === 120085));
你认为上面的代码会出现什么结果呢?1. true 2. false 3. 这种比较视情况而定
其实很简单,因为在这里,我们使用了 === 来做比较,所以这个结果很清晰的就是 false,
因为我们左边是一个 floats 类似的数,右边是一个 int 类型的数。
这是没什么可以特别讨论的。
那如果是这样呢?
die(var_dump(1200.85 * 100 == 120085));
就是我们使用 == 来比较的时候呢?
你可能会这样想:左边 120085,右边 120085,所以结果是 true。
如果你这样想的话,那你就错了。其实你运行上面的代码,结果回是 false。
然而,我是说然而!你再尝试修改一下数字,在运行一次代码,比如这样:
die(var_dump(1200.81 * 100 == 120081));
你会发现结果非常神奇,这个时候结果是 true,所以说,这种比较其实还真是视情况而定。
那么问题出现在哪里呢?我们试着运行下面的代码:
var_dump(1200.85 * 100);
die(var_dump(120085));
结果会类似这样:
float(120085) int(120085)
好像没看出什么核心区别,我们这样再试试:
die(var_dump(120085 - 1200.85 * 100));
这个时候的结果应该是这样:
float(1.4551915228367E-11)
这就说明问题了,其实这个结果并不是 0 ,而是一个很小的 floats 类似的数。
如果你看 PHP 文档的时候:http://php.net/manual/zh/language.types.float.php
有注意那个很大的 Warning 的话,你应该就会明白:这里的核心问题其实就是浮点数的精度!
那这样的话,我们如何比较才是我们期望的值呢?
答案就是使用 round() 函数,像是这样:
die(var_dump(round(1200.85 * 100) == 120085));
所以吧,在使用 PHP 做这些精度计算比较的时候,一定要实测它的比较结果,或者是使用一些保险的手段进行比较,不然就会吃大亏。
欢迎关注我的公众号“PHP学习网”,原创技术文章第一时间推送。
文章来源:https://www.viphper.com/3183.html