• 前端面试(原生js篇)


    一、面试题

    问:开发的时候有用到过 Math 吗?

    答:很多啊。比如生成 GUID 的时候,就会用到 Math.random() 来生成随机数。

    问:别的呢?比如向下取整、向上取整?

    答:向下取整是 floor(),向上取整是 ceil()。另外还可以用 round() 方法进行四舍五入的取整。

    问:如果我需要四舍五入并保留两位小数,应该怎么处理呢?

    答:可以直接用 toFixed() 方法,然后在方法中传入 2,以保留两位小数。

    问:那数字 1.335 通过 toFixed(2) 计算后,结果是什么呢?

    答:1.34 啊。

    问:哦?那 0.1 + 0.2 等于多少呢?

    答:阿咧?难道不是 0.3 么...

    问:emmmmmm...

    答:......

    问:js 在处理十进制计算的时候,会先转为二进制,计算之后再转回十进制。如果这个数是浮点数,就很容易出现误差。

       

    答:原来如此!

    问:在了解了这个情况之后,你能写一个精确计算的方法么?

     

    二、优化 toFixed()

    由于二进制的原因,如果只是简单的放大缩小倍率,得到的结果都是不完美的

    比如很多人推荐的:

    Math.formatFloat = function (f, digit) {
        var m = Math.pow(10, digit);
        return Math.round(f * m, 10) / m;
    }

    在处理 8716.425 这个数的时候就会出错

     

    经过多次尝试和查阅资料,我强烈推荐 Scott 大神的 toFixed() 方法,原链接:http://www.chengfeilong.com/toFixed

    可以先手动找到舍入位,如果该位置大于5,则手动进位,并去掉舍入位及其后面的所有字符

    Number.prototype.toFixed = function(length) {
      var carry = 0; //存放进位标志
      var num,multiple; //num为原浮点数放大multiple倍后的数,multiple为10的length次方
      var str = this + ''; //将调用该方法的数字转为字符串
      var dot = str.indexOf("."); //找到小数点的位置
      if(str.substr(dot+length+1,1)>=5) carry=1; //找到要进行舍入的数的位置,手动判断是否大于等于5,满足条件进位标志置为1
      multiple = Math.pow(10,length); //设置浮点数要扩大的倍数
      num = Math.floor(this * multiple) + carry; //去掉舍入位后的所有数,然后加上我们的手动进位数
      var result = num/multiple + ''; //将进位后的整数再缩小为原浮点数
      /*
      * 处理进位后无小数
      */
      dot = result.indexOf(".");
      if(dot < 0){
        result += '.';
        dot = result.indexOf(".");
      }
      /*
      * 处理多次进位
      */
      var len = result.length - (dot+1);
      if(len < length){
        for(var i = 0; i < length - len; i++){
          result += 0;
        }
      }
      return result;
    }

    这个方法我暂时没有发现有错误处理的数字。如果有小伙伴发现了,一定留言告诉我

    在进行浮点数运算的时候,即使计算结果不精确,也可以用这个方法对结果进行四舍五入操作,得到最终结果

     

    三、大数相加

    在 js 中,对于超大整数的运算,还存在格式问题

    当数字超出某个范围的时候,数字会自动转为科学计数法

    这个时候如果还需要输出常规格式,就需要将数字转为字符串,然后实现一个字符串加法

    function sumNumber(a, b) {
      var res = '', temp = 0;
      a = a.split('');
      b = b.split('');
      while (a.length || b.length || temp) {
        temp += ~~a.pop() + ~~b.pop();
        res = (temp % 10) + res;
        temp = temp > 9;
      }
      return res.replace(/^0+/, '');
    }

    来源:https://www.cnblogs.com/kindofblue/p/4672129.html

    这个方法的入参必须为整型的字符串,然后从个位开始,逐位相加,最后返回字符串

     

    相关:

    http://0.30000000000000004.com/ 

  • 相关阅读:
    武汉大学数学专业考研试题参考解答
    中山大学数学专业考研试题参考解答
    北京大学数学专业考研试题参考解答汇总
    一些泛函分析题目
    人生感言
    数学分析高等代数考研试题荟萃[更新至2017年12月28日]
    数学分析高等代数考研试题荟萃[更新至2017年12月15日]
    2017-2018-1 实变函数
    2017-2018-1 点集拓扑
    Latex "Error: Extra alignment tab has been changed to cr. "
  • 原文地址:https://www.cnblogs.com/wisewrong/p/9951388.html
Copyright © 2020-2023  润新知