二进制 的初识

125 阅读3分钟

必修课之二进制

N进制

公式:abc\pmb {abc} = a×N2+b×N1+c×N0\pmb {a} \times \pmb {N} ^ 2 + \pmb {b} \times \pmb {N} ^ 1 + \pmb {c} \times \pmb {N} ^ 0
  1. N进制的数字范围为: [0, N-1],大于N-1的就要向前进一位。
  2. 对于N进制,任意一个数字,它的大小就是各个位置的数字,乘以N的这个位置减1次方的和。
eg1:大小 为 10 进制大小
  1. 二进制 110 大小为:1 * 2^2 + 1 * 2^1 + 0 * 2 ^ 0 = 4 + 2 = 6
  2. 十进制 110 大小为: 1 * 100 + 1 * 10 + 0 = 110
  3. 八进制 110 大小为: 1 * 64 + 1 * 8 + 0 = 72
  4. 十六进制 110 大小为: 1 * 256 + 1 * 16 + 0 = 272

二进制

真值表
pqp 与 qp 或 q
0000
1001
0101
1111
eg1: AB=1A \bigcap B = 1 A,B同为1;AB=0A \bigcup B = 0 A,B同为0;

100011=000100 \bigcap 011 = 000; 100011=111100 \bigcup 011 = 111;

eg2: 给定一个数m,怎么判断 m 是不是 2 的 n 次方?
  1. m=2nm = 2^n
  2. m(m1)=0m \bigcap (m-1) = 0
//方法1 m = 2^n 
const is2Power = (m) => {
  if (m <= 0) {
    return false;
  }
  let num = m;
  while(num > 1){
    if (num % 2 !== 0) {
      return false;
    }
    num /= 2;
  }
  
  return true;
}
// 此处扩展一下 while 与 do……while 循环
// 语法:
// while (true) {……}
// do {……} while (true)
// 注:先判断再执行 与 先执行再判断的关系 如果条件为false 退出循环

// 方法2:
const is2Power2 = (m) => {
  if (m <= 0) {
    return false;
  }
  
  const logVal = Math.log2(m);
  return Math.floor(logVal) === logVal;
}
// 扩展:判断一个数是否为整数
// 1.使用 Math.round,Math.cell,Math.floor判断: Math.floor(num) === num;
// 2. num % 1 === 0; 注:类型转换导致的错误('', '3', [], [1], false) 需要加条件:typeof num === 'number';
// 3. parseInt(num, 10) === num; 1000000000000000000000 大数 转换为 1 导致结果出错
// 4. 位运算 (num | 0) === num; 注: 只能处理 32位以内的数字
// 5. ES6 提供了 Number.isInterger(num)方法

// 方法3:a ∩ (a - 1) = 0; m 是 2 的 n 次方
const is2Power3 = (m) => {
  return (m > 0) && ((m & (m - 1))) == 0);
}
// eg: a = 10000; a - 1 = 01111; 那么 a ∩ (a - 1) === 0
// 注:如果一个数 a 是 2 的 n 次方, 那么 a 的最高位就是1, 其他位就是 0, 那么 a - 1的最高位是 0 其他位是 1,才会有  a ∩ (a - 1) = 0 

parseInt方法:

上面代码有提到 parseInt 方法,知识点整理如下:

parseInt(string, radix?); 返回值为 对应进制整数 或者 NaN;

  • string: 要被解析的值。如果参数不是一个字符串,则将其转换为字符串(toString)。字符串开头的空白符将被忽略。
  • radix: 可选,[2,36], 表示被解析的进制,不传 默认为10。
  1. 基本用法

    parseInt('1024'); // 1024
    parseInt('   80'); // 80 如果字符串头部有空格,空格会被自动去除
    parseInt(0); // 0 如果第一个入参不是字符串,则优先转为字符串,再进行转换
    parseInt('99aa'); // 99 是从左往右依次转换,不能转为数字的字符停止转换,返回已经转好的部分。aa99>NAN
    parseInt('0x10'); // 16 如果字符串以0x或0X开头,parseInt会将其按照十六进制数解析
    parseInt('011'); // 如果字符串以0开头,将其按照10进制解析
    parseInt(011); // 9 如果参数以0开头,但不是字符串,则会先将数值转成字符串,然后解析 (011).toString() // 9 可以查询一下
    parseInt(10000000000000000000) // 1 会先转为科学技术法,('1e+21')再转为字符串,然后解析 
    parseInt(0.00000008) // 8 会先转为科学技术法('8e-7'),再转为字符串,然后解析 
    
  2. 进制转换

    parseInt('19', 10); // 19
    parseInt('11', 2); // 3
    parseInt('17', 8); // 15
    parseInt('1f', 16); // 31
    
    parseInt('-99', ''); // -99 如果第二个参数是0、undefined和null, '',则直接忽略。
    
eg4:

之前招银前端笔试题遇到一个题,写出一个方法 #EEEEEE => rgb 格式;"#FFFFFF" => "rgb(255, 255, 255)";

const changeHandler = (str = '') => {
  let colorStr = '';
  if (str.length === 3) {
    colorArr = str.split('').reduce((pre, cur, index) => {
      const num = parseInt(`0x${cur + cur}`);
      if (!isNaN(num)) {
         pre.push(num);
      }
      return pre;
    }, []);
    colorStr = colorArr.toString()
  }
  if (str.length === 6) {
    const colorArr = str.split('').reduce((pre, cur, index, arr) => {
      if ((index + 1) % 2 === 0) {
        const num = parseInt(`${arr[index - 1]}${cur}`, 16);
        if (!isNaN(num)) {
           pre.push(num);
        }
      }
      return pre;
    }, []);
    colorStr = colorArr.join();
  }
  
  return colorStr && `rgb(${colorStr})`;
}

总结

此文只是记录学习过程中的心得体会,文章可读性不是很高,类似于学习笔记,加上一些自己的总结,整理。当然,上边的各种方法肯定还有很多欠缺或者不足,希望大家给出更多的观点,以及对于一些知识点进行延伸,我可以对延伸的知识点进行整理,希望或者,对于文中的代码,可以以更高效或优美的形式呈现,提出来大家一起学习,岂不美哉。希望大家一起探讨!