深入JS 之 【JS'骚'操作之0.1 + 0.2 !== 0.3】【手摸手图解函数底层运行机制】

265 阅读1分钟

6. JS'骚'操作之0.1 + 0.2 !== 0.3

  • 十进制转换为二进制的计算 [val].toString(2) // 参数是进制 范围 2~36
    • 整数部分 除二取余
    • 小数部分 乘二取整
  • JS使用number类型表示数字(整数和浮点数),遵循IEEE-754 标准 通过64位二进制值来表示一个数字https://babbage.cs.qc.cuny.eduIEEE-754.old/Decimal.html
    • 第0位:符号位,0表示正数,1表示负数 S 第1位到第11位「11位指数」:储存指数部分 E 第12位到第63位「52位尾数」:储存小数部分(即有效数字)F 注:尾数部分在规约形式下第一位默认为1(省略不写)
  • 最大安全数字「16位」 Number.MAX_SAFE_INTEGER === Math.pow(2,53)-1
  • 怎么解决精度问题?
    • 将数字转成整数【扩大系数】
    • 第三方库:Math.js、 decimal.js、 big.js 面试题:自己编写程序,把十进制的'整数'转换为二进制
// decimal十进制数
// binary 二进制
// negative 负数
// integer整数
const decimal2binary = function decimal2binary(decimal){
  let binary = [],
      negative = decimal < 0,
      integer;
  decimal = Math.abs(decimal)
  integer = Math.floor(decimal / 2)
  binary.unshift(decimal % 2)
  while(integer){
     binary.unshift(decimal % 2)
     integer = Math.floor(decimal / 2)
  }
  return `${negative?'-':''}${binary.join('')}`     
}
// 浮点数在计算机底层存储的时候,存储的二进制值可能被舍掉一部分【因为最多只有64位】,所以本身和原来的十进制就不一样了“精准度问题”
// '0011111110111001100110011001100110011001100110011001100110011010'  0.1
// '0011111111001001100110011001100110011001100110011001100110011010'  0.2
//  0.1 + 0.2 计算机底层会根据其二进制进行处理,最后转换为十进制给浏览器,这样也是一个很长的值 例如:可能是这样的 0.3000000000000400000000... 但是浏览器也会存在长度的限制,会截掉一部分;最后面全是零的省略掉...

// 解决方案:乘以一定的系数,变为整数进行运算,运算的结果再除以系数
// console.log(((0.1 * 10) + (0.2 * 10)) / 10 === 0.3); //=>true
// 获取系数
const coefficient = function coefficient(num){
  num = num + ''
  let [, char = ''] = num.split('.'),
      len = char.length;
  return Math.pow(10, len)
}
// 求和操作
const plus = function plus(num1, num2){
  num1 = +num1
  num2 = +num2
  if(isNaN(num1) || isNaN(num2)) return NaN
  let coeffic = Math.max(coefficient(num1),coefficient(num2))
  return (num1 * coeffic + num2 * coeffic) / coeffic 
}

7. 手摸手图解函数底层运行机制

  • 以下代码作为运行示例
var x = [12, 23];

function fn(y) {
    y[0] = 100;
    y = [100];
    y[1] = 200;
    console.log(y);
}

fn(x);
console.log(x);

函数底层运行机制.png

如果觉得还可以,麻烦XDM点个赞,点击下面的进入专栏可以看到其他的文章!!!!