【小程序】微信小程序的大数运算库

这是一个十分轻量级的用于微信小程序的大数运算库

它的功能有:

  • 2进制-32进制数运算
  • 大整数加(正负均可)
  • 大整数减(正负均可)
  • 大整数乘(正负均可)
  • 大整数除(正负均可,得出的结果为整数,抹去小数部分)
  • 大整数取余(得出的结果恒为正数)
  • 大整数随机数生成

使用方法:

首先把下载好的weChatBigNumber.js文件放入微信小程序的 项目根目录/utils 文件夹下。
之后在需要的页面添加此语句:

var bigNum = require('../../utils/weChatBigNumber.js')

然后调整进制:
在weChatBigNumber.js文件中,有一个名为radix的用十进制表示的变量。我们通过修改它的值,来达到更改进制的目的。

var radix = 16;

之后就可以调用大数运算库中的方法了:

函数 实例 说明
add(x,y) bigNum.add(x,y) 将x,y两个字符串相加,返回值为x+y的结果字符串。
subtract(x,y) bigNum.subtract(x,y) 将x,y两个字符串相减,返回值为x-y的结果字符串。
multiply(x,y) bigNum.multiply(x,y) 将x,y两个字符串相乘,返回值为x*y的结果字符串。
divide(x,y) bigNum.divide(x,y) 将x,y两个字符串相除,返回值为x/y的结果字符串。注意:结果只保留整数部分。
mod(x,y) bigNum.mod(x,y) 将x,y两个字符串取余,返回值为x%y的结果字符串。注意:y必须为正,结果恒为整数。
randomNum(x) bigNum.randomNum(x) 生成0-x的随机大整数。

核心实现代码(无符号大数运算部分):

大数无符号加:

function addWithoutSign(a, b) {
  var lena = a.split('').length;
  var lenb = b.split('').length;

  a = a.split('').reverse();
  b = b.split('').reverse();

  var total = [];
  let addFlag = 0;

  if (lena >= lenb) {
    for (let i = 0, j = 0; i < lena; i++ , j++) {
      if (j < lenb) {
        total[i] = parseInt(a[i], radix) + parseInt(b[j], radix) + addFlag;
        total[i] = total[i].toString(radix);
      } else {
        total[i] = parseInt(a[i], radix) + addFlag;
        total[i] = total[i].toString(radix);
      }
      var tempTotal = parseInt(total[i], radix);
      if (tempTotal >= radix) {
        total[i] = (tempTotal - radix).toString(radix);
        if (i == (lena - 1)) {
          total[lena] = '1';
        }
        addFlag = 1;
      } else {
        addFlag = 0;
      }
    }
    total = total.reverse().join('');
    return total;
  } else {
    for (let i = 0, j = 0; i < lenb; i++ , j++) {
      if (j < lena) {
        total[i] = parseInt(a[j], radix) + parseInt(b[i], radix) + addFlag;
        total[i] = total[i].toString(radix);
      } else {
        total[i] = parseInt(b[i], radix) + addFlag;
        total[i] = total[i].toString(radix);
      }

      var tempTotal = parseInt(total[i], radix);
      if (tempTotal >= radix) {
        total[i] = (tempTotal - radix).toString(radix);
        if (i == (lenb - 1)) {
          total[lenb] = 1;
        }
        addFlag = 1;
      } else {
        addFlag = 0;
      }
    }
    total = total.reverse().join('');
    return total;
  }
}

大数无符号减:

function subtractWithoutSign(a, b) {
  a = a + '';
  b = b + '';

  var result = [];
  var output = [];
  var minusOne = 0;

  a = ltrimZero(a);
  b = ltrimZero(b);

  //补0对齐
  while (a.length < b.length) {
    a = '0' + a;
  }
  while (b.length < a.length) {
    b = '0' + b;
  }
  //从后面位数向前相减
  for (var i = a.length - 1; i >= 0; i--) {
    var c1 = parseInt(a.charAt(i), radix) - 0;
    var c2 = parseInt(b.charAt(i), radix) - 0;
    //如果当前位数无须借位
    if (c1 - minusOne >= c2) {
      result.unshift(c1 - c2 - minusOne);
      output.unshift((c1 - c2 - minusOne).toString(radix));
      minusOne = 0;
    } else {
      result.unshift(c1 + radix - c2 - minusOne);
      output.unshift((c1 + radix - c2 - minusOne).toString(radix));
      minusOne = 1;
    }
  }
  //如果最高位仍然要借位
  if (minusOne) {
    var newResult = subtract(b, a);
    newResult = ltrimZero(newResult);
    return '-' + newResult;
  }

  result = result.join('');
  output = output.join('');
  result = ltrimZero(result);
  output = ltrimZero(output);
  if (output == '') {
    output = '0';
  }
  return output;
}

大数无符号乘:

function multiplyWithoutSign(a, b) {
  var str1, str2, len1, len2, maxlen;
  var result = [];
  var output = [];
  str1 = a.split('').reverse();
  str2 = b.split('').reverse();
  len1 = str1.length;
  len2 = str2.length;

  for (var i = 0; i < len1; i++) {
    for (var j = 0; j <= len2; j++) {
      result[i + j] = 0;
      output[i + j] = result[i + j].toString(radix);
    }
  }

  for (var i = 0; i < len1; i++) {
    for (var j = 0; j < len2; j++) {
      result[i + j] += parseInt(str1[i], radix) * parseInt(str2[j], radix);
      output[i + j] = result[i + j].toString(radix);
    }
  }

  var n = result.length;
  for (var k = 0; k < n; k++) {
    var temp = result[k];
    if (temp >= radix) {
      result[k] = temp % radix;
      result[k + 1] += Math.floor(temp / radix);
      output[k] = result[k].toString(radix);
      output[k + 1] = result[k + 1].toString(radix);
    }
  }

  output = output.reverse().join('');
  output = ltrimZero(output);
  if (output == '') {
    output = '0';
  }
  return output
}

大数无符号除:

function divideWithoutSign(a, b) {
  a = a + '';
  b = b + '';

  if (compare(a, b) < 0) {
    return '0';
  } else if (compare(a, b) == 0) {
    return '1';
  }

  var alen = a.length;
  var blen = b.length;
  var times = alen - blen + 1;
  var result = [];

  for (var c = 0; c < times; c++) {
    var tempb = b;
    result[c] = 0;
    //补0
    while (tempb.length < alen - c) {
      tempb = tempb + '0';
    }
    while (compare(a, tempb) >= 0) {
      result[c]++;
      a = subtract(a, tempb);
    }
  }

  for (var c = 0; c < result.length; c++) {
    result[c] = result[c].toString(radix);
  }
  var output = ltrimZero(result.join(''));
  return output;
}

大数取余:

function mod(a, b) {
  a = a + '';
  b = b + '';
  if (b.indexOf('-') != -1) {
    return 'b只能为正数';
  }
  // a - (a/b)*b
  var output = divide(a, b);
  output = multiply(output, b);
  output = subtract(a, output);

  if (output.indexOf('-') != -1) {
    output = add(output, b);
  }
  return output;
}

随机大数生成:

function randomNum(n) {
  n = n + '';
  var flag = 10000000000000000;
  var randomWithoutRadix = Math.random();
  var random = randomWithoutRadix.toString(radix);
  var randomOutput = random.substr(random.indexOf('.') + 1, random.length);
  var multiplyNum = multiply(randomOutput, n);
  var finalNum = divide(multiplyNum, flag.toString(radix));
  return finalNum;
}

具体代码下载-> GitHub:
https://github.com/shadowings-zy/weChatBigNumber.

扫描二维码关注公众号,回复: 3529266 查看本文章

猜你喜欢

转载自blog.csdn.net/u011748319/article/details/80300584