zoukankan      html  css  js  c++  java
  • PHP的intval函数的运行机制,intval(0.58*100)输出 57

    今天PHP的学员去面试,其中一道面试题是echo intval(0.58*100) 输出多少,为什么?

    按照正常思维输出58 ,但是运行结果是57,然后在尝试

    intval(0.68*100)输出 68

    intval(0.56*100)输出 56

    intval(0.57*100)输出 56

    intval(0.58*100)输出 57

    intval(0.59*100)输出 59

    为什么只是0.57*100和0.58*100会特殊呢?

    首先我们来看intval()在PHP 的 Manual 里有写,是 intval() 这个函数的问题,采用的是“截断”法取整。

    这个问题看似奇特,其实还是浮点数的精度的问题,0.58*100 的结果是什么?其实大家试试就知道了,并不是想象中的 58,而是 57.99999999999999,为什么会这样 我们先来说下计算机中保存浮点数 不能精确表示,本篇可能比较烧脑子,我会尽量用最通俗的语言,最贴近现实的例子来讲解,不在乎篇幅有多长,关键是要给大家讲明白。下一篇,你将了解到浮点数如何工作,以及为什么很多数 不能表示。

    热身 —— 问:要把小数装入计算机,总共分几步?你猜对了,3 步。

    • 第一步:转换成二进制

    • 第二步:用二进制科学计算法表示

    • 第三步:表示成 IEEE 754 形式

    在上面的第一步和第三步都有可能 丢失精度。

    下面我们讨论如何把十进制小数转换成二进制小数(什么?你不会?请自觉去面壁)。考虑我们将 1/7(七分之一) 写成小数的时候是如何做的?用 1 除以 7,得到的商就是小数部分,剩下的余数我们继续除以 7,一直除到什么时候结束呢? 有两种情况:

    1. 如果余数为 0。yeah!终于结束了,洗洗睡吧

    2. 当除到某一步时,余数等于 1… 停!stop!等一下,我发现有什么地方怪怪的。余数为 1,余数如果为 1 的话,再继续除下去,不就又是 1/7 了吗?绕了一个大弯,又回来了?对,你猜的很对,它永远不会结束,它循环了。注意我上面说的 情况2,我们判断他循环,并 不是从直观看感觉它重复了,而是因为在计算过程中,它又回到了开头。为什么这么说呢?当你计算一个分数时,它总是连续出现 5,出现了好多次,例如 0.5555555… 你也无法断定它是无限循环的,比如 一亿分之五

    其实 0.58*100 = 57.99999999999999 是不局限于任何语言的,是 IEEE 规定的浮点数的运算标准。一般情况下,57.99999999999999 会四舍五入到 58。需要注意的是,浮点数的四舍五入和咱们普通的数学里面的也是不同的,浮点数遇到 5 后,不一定总是入,有时也舍,具体细节不多解释了。

    为什么结果是 57 呢,主要是因为 intval 函数的规则是,从第一个数字开始,知道遇到不是数字的字符,结束。

  • 相关阅读:
    Centos 7 zabbix 实战应用
    Centos7 Zabbix添加主机、图形、触发器
    Centos7 Zabbix监控部署
    Centos7 Ntp 时间服务器
    Linux 150命令之查看文件及内容处理命令 cat tac less head tail cut
    Kickstart 安装centos7
    Centos7与Centos6的区别
    Linux 150命令之 文件和目录操作命令 chattr lsattr find
    Linux 发展史与vm安装linux centos 6.9
    Linux介绍
  • 原文地址:https://www.cnblogs.com/zhang0807/p/10581040.html
Copyright © 2011-2022 走看看