📜  定义一个 unsigned long int js - Javascript (1)

📅  最后修改于: 2023-12-03 15:09:26.394000             🧑  作者: Mango

定义一个 unsigned long int js - Javascript

在JavaScript中,没有像C或C++中的unsigned long int类型。但是,可以借助一些技巧来模拟实现。

1. 手动模拟

我们可以手动模拟一个64位的无符号整数,使用两个32位的有符号整数来表示。其中高32位为整数的符号位(0表示正数,1表示负数),低32位为整数值。这种表示方法可以表示的最大值为2^64-1。

class UnsignedLong {
  constructor(high, low) {
    this.high = high >>> 0; // 保证为无符号整数
    this.low = low >>> 0; // 保证为无符号整数
  }

  value() {
    return (this.high << 32) | this.low;
  }

  toString() {
    const radix = 10; // 进制
    const digitOnMask = 9; // 每个数字对应的掩码位数
    const separator = ',';
    const digitList = [];

    let high = this.high;
    let low = this.low;

    // 处理低32位
    for (let i = 0; i < digitOnMask; i++) {
      digitList.push(low % radix);
      low = Math.floor(low / radix);
    }

    // 处理高32位
    while (high > 0) {
      let remainder = high % radix;
      high = Math.floor(high / radix);
      
      // 把高32位的每一位数字加入digitList
      for (let i = 0; i < digitOnMask; i++) {
        remainder *= radix;
        
        // 如果digitList不为空,最低位需要加上已存在的数字,其它位直接填0
        if (i === 0 && digitList.length > 0) {
          remainder += digitList[digitList.length - 1];
        }
        
        digitList.push(remainder % radix);
      }
    }
    
    // 去掉前导0
    while (digitList.length > 1 && digitList[digitList.length - 1] === 0) {
      digitList.pop();
    }

    // 用separator分隔每3位数字
    for (let i = 0; i < digitList.length / digitOnMask - 1; i++) {
      digitList.splice((i + 1) * digitOnMask + i, 0, separator);
    }

    return digitList.reverse().join('');
  }
}

const a = new UnsignedLong(0x12345678, 0x9abcdef0);
console.log(a.value()); // 1369375960843473400
console.log(a.toString()); // 123,456,789,abcdef0
2. 使用BigInt

自JavaScript的ES2020标准开始,引入了BigInt类型,可以表示任意大的整数。使用BigInt的方式可以更加简单。

const a = BigInt('0x123456789abcdef0');
console.log(a.toString(10)); // "1311768467463790320"
总结

以上两种方法都可以实现类似于unsigned long int的无符号整数类型。手动模拟的方式可以更好地掌握位运算等基础概念,但存在代码量较多的问题;使用BigInt的方式更加简单,但在某些环境下(例如老版本的Node.js、IE等)可能不被支持。选择哪种方式需要根据实际情况来决定。