PHP 什么情况下 5.590 小于 5.59

2017-07-26 16:51:34 +08:00
 solaro

上图实际开发业务中,碰到了个坑,

数据库用的 mysql 左边 5.590 在数据库中存储是 decimal(10,3) 右边是换算出来的 float

现在 floatval(5.590) < floatval(5.59)

我 sun

4918 次点击
所在节点    PHP
43 条回复
elgae
2017-07-26 16:56:51 +08:00
关系到钱的业务用浮点数,心很大。
7654
2017-07-26 17:00:41 +08:00
有个故事,某企财务将全厂工资的几分零头抹掉,每月可偷几千块
Jacklee
2017-07-26 17:03:50 +08:00
计算机存储浮点型都不是精确的,如楼上所说,不能直接比较大小啊。涉及钱的业务更不能用啊。
Jacklee
2017-07-26 17:04:25 +08:00
补一句,这不是 PHP 的锅哈
oh
2017-07-26 17:09:27 +08:00
抛去楼上已解决说的,不知道楼主有没有试过在 if 前面 var_dump(floatval()) 看看这两个变量对比的时候是多少?
Biscuits
2017-07-26 17:12:44 +08:00
5.59 可能是 5.5904444
bombless
2017-07-26 17:12:46 +08:00
比较的时候乘 100 按整数比吧
lujiajing1126
2017-07-26 17:12:52 +08:00
楼主需要复习一下 IEEE754
goodspb
2017-07-26 17:12:56 +08:00
php > var_dump(floatval(5.590) < floatval(5.59));
php shell code:1:
bool(false)
php > var_dump(floatval(5.590) == floatval(5.59));
php shell code:1:
bool(true)
php > var_dump(5.590 == 5.59);
php shell code:1:
bool(true)
php > var_dump(5.590 < 5.59);
php shell code:1:
bool(false)

恩?有啥问题?

php -v 一下

PHP 5.6.30 (cli) (built: Apr 17 2017 10:09:18)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
with Xdebug v2.5.3, Copyright (c) 2002-2017, by Derick Rethans
ovear
2017-07-26 17:14:02 +08:00
请使用 bccomp
exch4nge
2017-07-26 17:14:53 +08:00
对 PHP 不熟悉……不过表示金钱的类型应该用专门的 decimal 类型吧……
nfroot
2017-07-26 17:15:19 +08:00
@bombless 加减乘除都这样么 0 0
gclove
2017-07-26 17:15:50 +08:00
同上, 计算千万不要用符点, 还不如用大数计算

建议直接乘 100 取整
为什么设置 3 位, 你们应用还有微分 ?
有的话可以乘以 1000 取整

浮点在每种变成语言都有陷阱(坑), 经验不够老练都会踩上
gclove
2017-07-26 17:21:30 +08:00
非用浮点, 计算前值一定要进行类型转换

因为你不知道它是 整数, 浮点, 还是 字符串
solaro
2017-07-26 17:21:38 +08:00
本地开发环境用 5.6.27 没毛病,生产环境用 7.1 就触发异常。。。我日
doushiyinweini
2017-07-26 17:24:10 +08:00
moult
2017-07-26 17:25:36 +08:00
就算知道什么情况下出现这个问题,那又如何?
1、从数据库里面查询出来的浮点数,请使用 string。
2、http://php.net/manual/en/book.bc.php
3、个人癖好,有段时间,金钱我用 int 来存储,单位是分。不过现在都用 string 来做了。
solaro
2017-07-26 17:31:57 +08:00
@moult 为什么,请老司机传道受业解惑,int 不够用我可以理解,bigint 不好吗?为什么换 string
solaro
2017-07-26 17:32:46 +08:00
@elgae 早期留下的坑
zhs227
2017-07-26 17:34:48 +08:00
涉及到价格我每次都是*100 以后按整数存。float 的比较容易出问题,越相近越容易出问题。

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

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

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

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

© 2021 V2EX