这是一个 PHP 的 整数 浮点数转换 bug?

2023-07-08 22:44:54 +08:00
 haha512

// php 8.0 - 8.2 
// floatval  函数用于获取变量的浮点值  
// intval() 函数用于获取变量的整数值。

php -r 'echo floatval("2.51");'  >> 2.51

php -r 'echo floatval(2.51);'		>>2.51

php -r 'echo intval(251);'		>> 251
php -r 'echo intval("251");'	>> 251


php -r 'echo floatval("2.51")*100;'	>> 251

php -r 'echo floatval(2.51)*100;'	>> 251




// bug 来了 floatval("2.51")*100 根据上面可知是 251 ,也可知 intval(251)===251
php -r 'echo (int)( floatval("2.51")*100 );'	>> 250
php -r 'echo intval( floatval("2.51")*100 );'	>>250



1706 次点击
所在节点    程序员
12 条回复
Worldispow
2023-07-08 23:00:19 +08:00
churchill
2023-07-08 23:01:53 +08:00
不算 bug 吧
大部分语言的取整实现都是 truncate towards zero
250.999999 ~取整可不就是 250 嘛
veike
2023-07-09 01:37:35 +08:00
php -r 'echo (int) bcmul("2.51", "100");' 结果为 251
mingl0280
2023-07-09 08:02:41 +08:00
建议楼主回去复习 IEEE-754 浮点数。
这属于浮点数的基本知识了,浮点数不是精确等于某个值的。
darkengine
2023-07-09 10:02:19 +08:00
不是语言的问题,基本上每个平台/语言都会遇到
NessajCN
2023-07-09 10:13:35 +08:00
Python:
>>> 2.51*100
250.99999999999997

NodeJS:
> 2.51*100
250.99999999999997

另外楼主可以试试经典的 0.1+0.2
lysS
2023-07-09 11:14:45 +08:00
0.251 应该不能用那几位二进制精确表示,用的是近似值
llh880808
2023-07-09 15:19:31 +08:00
浮点数的表达范围为什么能远远大于整型数,这一定是有取舍的,舍去的就是精度

浮点数的特点是在 0 附近的精度相当高,越靠近±无穷大精度就越差,可以想象当数字大到一定程度,(浮点数)连整数的精度都保证不了

因此不要预期 2.51 (更靠近 0 )和 251 会有完全一致的行为
zhangtest
2023-07-09 17:34:16 +08:00
php 计算相关的用这个
https://www.php.net/manual/zh/ref.bc.php
well775397252
2023-07-09 20:03:07 +08:00
不是 bug
woojanelook
2023-07-10 10:39:44 +08:00
php 涉及浮点计算的都要使用 bc 函数
Symo
2023-07-10 11:03:06 +08:00
浮点数的 round floor ceil 还是通过 bcmath 的方式显式指定,依赖默认转换很容易出问题

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

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

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

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

© 2021 V2EX