• 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 函数的规则是,从第一个数字开始,知道遇到不是数字的字符,结束。

  • 相关阅读:
    powerdesigner添加mysql的字符集ENGINE和DEFAULT CHARACTER SET
    powerdesigner怎么设置同时显示name和code
    更改gradle的java的class文件输出目录的结构
    使用TortoiseGit时如何实现SSH免密码登录
    TortoiseGit之配置密钥
    Mock InjectMocks ( @Mock 和 @InjectMocks )区别
    Centos tomcat jmx 远程连接
    【C++】常见易犯错误之数值类型取值溢出与截断(3)
    【C++】常见易犯错误之数值类型取值溢出与截断(2)
    【C++】常见易犯错误之数值类型取值溢出与截断(1)
  • 原文地址:https://www.cnblogs.com/zhang0807/p/10581040.html
Copyright © 2020-2023  润新知