• 你好!欢迎你的到来
  • 关于我们
  • 首页 博客 学习笔记 技术导航 工具
  • 博文分类
    • PHP(43)
    • MySQL(11)
    • Linux(28)
    • html(3)
    • JQuery(4)
    • JavaScript(9)
    • svn(2)
    • CSS(2)
    • seajs(1)
    • go(44)
    • redis(1)
    • nginx(8)
    • mongo(0)
    • es(0)
    • 算法(0)
    • 其他(26)
    • 生活(1)
    专栏
    • Jquery基础教程
      • 文章:(15)篇
      • 阅读:17794
    • shell命令
      • 文章:(42)篇
      • 阅读:61198
    • Git教程
      • 文章:(36)篇
      • 阅读:119127
    • leetCode刷题
      • 文章:(37)篇
      • 阅读:15713
    • 摘要视图
    • 目录视图
    PHP7中对大数求余报错Uncaught DivisionByZeroError: Modulo by zero
    标签: 整型溢出
    2018-03-13 21:56 阅读(5660) 评论(2)

    一、问题描述

    今天在使用PHP中的求余的时候,发现了一个“很怪异的事”,

    在PHP中执行如下代码

    echo 2 % pow(2,32);

    既然报错:

    PHP Fatal error:  Uncaught DivisionByZeroError: Modulo by zero in Command line code:1

    Stack trace:

    #0 {main}

      thrown in Command line code on line 1

    Fatal error: Uncaught DivisionByZeroError: Modulo by zero in Command line code:1

    Stack trace:

    #0 {main}

      thrown in Command line code on line 1

    换了台机器,既然能够执行成功,如下:

    32位系统执行如下:

    当在64位系统中,却能正常如下:

    当时觉得不可以思议,最后好好比较了一下两台机器的区别,发现原来是一台32位,一台64位,于是就猜想可能是PHP整形溢出的问题。

    通过查阅手册发现,原来PHP的int类型的字长

    在32位系统上面,int是4个字节,取值范围为:-2147483648(231) ~ 2147483647(231 - 1)

    在64位系统上面,int是8个字节,取值范围为:-2147483648(263) ~ 2147483647(263 - 1)

    超过int范围,就会导致整型溢出,如下:

    PHP官方手册上面说,超出整型int的表示范围,就会自动隐式地转为float类型。

    故在32位操作系统上面232以float类型表示,可以在命令行中执行如下命令验证:

    php -r '$a = pow(2,32); var_dump(is_float($a));';    //bool(true)

    php在对数值取模运算时会把浮点数float隐式地转为int类型再取模,浮点数转换成整数时,将向下取整。

    如果浮点数超出了整数范围,则结果为未定义,因为没有足够的精度给出一个确切的整数结果。在此情况下没有警告,甚至没有任何通知!

    看来有时间得看看PHP源码了。当int类型溢出的时候,会变成什么数呢?这个问题回头得好好看看。

    二、问题的解决

    既然整型会溢出,那么,我们可以使用浮点型float类型,但是PHP在使用%运算符的时候,会隐式地转为int类型,怎么办呢?这时候,fmod函数派上了用场,语法如下:

    float fmod ( float $x , float $y )

    对超过php的int类型取余,可以使用如下方面:

    var_dump(fmod(14, pow(2,32))); //14

    三、类似问题

    1、数字和字符串的比较

    首先,来看看个案例,如下:

    var_dump(in_array(0, [3,"a", 6, "b"]));
    var_dump(array_search(0, [3,"a", 6, "b"]));
    var_dump(0 == 'a');
    var_dump(in_array('dequan', [true, 'de', 'quan']));

    执行结果如下:

    为什么都是ture?

    关键在于比较前,php做了类型转换。

    2、php中浮点数精度问题



    其实,所谓的诡异,往往源自于知识的缺乏。

    本文为原创文章,请尊重辛勤劳动,如需转载,请保留本文地址
    http://www.findme.wang/blog/detail/id/386.html

    若您感觉本站文章不错,读后有收获,不妨赞助一下?

    我要赞助

    您还可以分享给朋友哦

    更多
    顶
    7
    踩
    1
    • 上一篇: PHP中有效地获取最后一次报错
    • 下一篇: php中trait的使用
    • 查看评论
    • 正在加载中...
    • 留言
    • 亲,您还没有登录,登录后留言不需要审核哦!
      可以使用如下方式登录哦!
  • CSDN | 新浪微博 | github | 关于我们 | 我要留言 | 友链申请
  • 豫ICP备18038193号    Copyright ©lidequan All Rights Reserved