多语言展示
当前在线:653今日阅读:23今日分享:25

易语言编程中超长整数累加的JS方法

易语言中会遇到整数累加的控制方式,但是他的整数累加还是有很多问题,如显示不正常啊之类的,本文通过JS的方式来提供超长位数的整数累加效果,同时也提供易语言脚本组件的使用方法.
工具/原料

易语言5.11

方法/步骤
1

首先我们定义一个整数变量,对11位以上的整数进行累加查看输出结果,结果位10位整数且没任何联系的.

2

那我们将被累加数的定义为长整数变量时,对于较短的整数还是可以的,但是位数提高到19位还是出现累加错误

方法/步骤2
1

以上两种方式都会有这样那样的问题,那么我们来看看利用JS方式来操作

2

首先添加一个脚本组件,属性默认即可

3

其次添加一个长文本常量,命名随意,我这里命名为'js大数运算'常量内容如下:// BigInt.js - Arbitrary size integer math package for JavaScript// Copyright (C) 2000 Masanao Izumo // Version: 1.0.1// Licence: GPL//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.////// Interfaces:// x = new BigInt('23456789');// y = new BigInt('0x123456789abcdefabcdef0');// z = x.clone();// z = bigint_uminus(x);// z = bigint_plus(x, y);// z = bigint_minus(x, y);// z = bigint_mul(x, y);// z = bigint_div(x, y);// z = bigint_mod(x, y);// cmp = bigint_cmp(x, y); /* return -1, 0, or 1 */// num = bigint_number(x); /* convert normal number (may be floating) *///function _BigInt_toString(){    return this.toStringBase(10);}function _BigInt_toStringBase(base){    var i, j, hbase;    var t;    var ds;    var c;    i = this.len;    if(i == 0)      return '0';    if(i == 1 && !this.digits[0])      return '0';    switch(base) {      default:      case 10:      j = Math.floor((2*8*i*241)/800)+2;      hbase = 10000;      break;      case 16:      j = Math.floor((2*8*i)/4)+2;      hbase = 0x10000;      break;      case 8:      j = (2*8*i)+2;      hbase = 010000;      break;      case 2:      j = (2*8*i)+2;      hbase = 020;      break;    }    t = this.clone();    ds = t.digits;    s = '';    while (i && j) {      var k = i;      var num = 0;      while (k--) { num = (num<<16) + ds[k]; if(num < 0) num += 4294967296; ds[k] = Math.floor(num / hbase); num %= hbase;      }      if (ds[i-1] == 0)        i--;      k = 4;      while (k--) { c = (num % base); s = 'abcdef'.charAt(c) + s; --j; num = Math.floor(num / base); if (i == 0 && num == 0) {  break; }      }    }    i = 0;    while(i < s.length && s.charAt(i) == '0')      i++;    if(i)      s = s.substring(i, s.length);    if(!this.sign)      s = '-' + s;    return s;}function _BigInt_clone(){  var x, i;  x = new BigInt(this.len, this.sign);  for(i = 0; i < this.len; i++)    x.digits[i] = this.digits[i];  return x;}function BigInt(len, sign){  var i, x, need_init;  // Setup member functions.  // Note: There is G.C. bug of function() in Netscape!  //       Don't use anonymous function.  this.toString = _BigInt_toString;  this.toStringBase = _BigInt_toStringBase;  this.clone = _BigInt_clone;  if(BigInt.arguments.length == 0) {    this.sign = true;    this.len = len = 1;    this.digits = new Array(1);    need_init = true;  } else if(BigInt.arguments.length == 1) {    x = bigint_from_any(BigInt.arguments[0]);    if(x == BigInt.arguments[0])      x = x.clone();    this.sign = x.sign;    this.len = x.len;    this.digits = x.digits;    need_init = false;  } else {    this.sign = (sign ? true : false);    this.len = len;    this.digits = new Array(len);    need_init = true;  }  if(need_init) {    for(i = 0; i < len; i++)      this.digits[i] = 0;  }}function bigint_norm(x){  var len = x.len;  var ds = x.digits;  while(len-- && !ds[len])    ;  x.len = ++len;  return x;}function bigint_from_int(n){  var sign, big, i;  if(n < 0) {    n = -n;    sign = false;  } else    sign = true;  n &= 0x7fffffff;  if(n <= 0xffff) {    big = new BigInt(1, 1);    big.digits[0] = n;  } else {    big = new BigInt(2, 1);    big.digits[0] = (n & 0xffff);    big.digits[1] = ((n>>16) & 0xffff);  }  return big;}function bigint_from_string(str, base){  var str_i;  var sign = true;  var c;  var len;  var z;  var zds;  var num;  var i;  var blen = 1;  str += '@'; // Terminator;  str_i = 0;  // TODO: skip white spaces  if(str.charAt(str_i) == '+') {    str_i++;  }  else if (str.charAt(str_i) == '-') {    str_i++;    sign = false;  }  if (str.charAt(str_i) == '@')    return null;  if (!base) {    if (str.charAt(str_i) == '0') {      c = str.charAt(str_i + 1);      if (c == 'x' || c == 'X') { base = 16;      }      else if (c == 'b' || c == 'B') { base = 2;      }      else { base = 8;      }    }    else {      base = 10;    }  }  if (base == 8) {    while (str.charAt(str_i) == '0')      str_i++;    len = 3 * (str.length - str_i);  }  else { // base == 10, 2 or 16    if (base == 16 && str.charAt(str_i) == '0' && (str.charAt(str_i+1) == 'x' || str.charAt(str_i+1) == 'X')) {      str_i += 2;    }    if (base == 2 && str.charAt(str_i) == '0' && (str.charAt(str_i+1) == 'b'||str.charAt(str_i+1) == 'B')) {      str_i += 2;    }    while (str.charAt(str_i) == '0')      str_i++;    if (str.charAt(str_i) == '@') str_i--;    len = 4 * (str.length - str_i);  }  len = (len>>4)+1;  z = new BigInt(len, sign);  zds = z.digits;  while(true) {    c = str.charAt(str_i++);    if(c == '@')      break;    switch (c) {    case '0': c = 0; break;    case '1': c = 1; break;    case '2': c = 2; break;    case '3': c = 3; break;    case '4': c = 4; break;    case '5': c = 5; break;    case '6': c = 6; break;    case '7': c = 7; break;    case '8': c = 8; break;    case '9': c = 9; break;    case 'a': case 'A': c = 10; break;    case 'b': case 'B': c = 11; break;    case 'c': case 'C': c = 12; break;    case 'd': case 'D': c = 13; break;    case 'e': case 'E': c = 14; break;    case 'f': case 'F': c = 15; break;    default:      c = base;      break;    }    if (c >= base)      break;    i = 0;    num = c;    while(true) {      while (i>>= 16;      }      if (num) { blen++; continue;      }      break;    }  }  return bigint_norm(z);}function bigint_from_any(x){  if(typeof(x) == 'object') {    if(x.constructor == BigInt)      return x;    return BigInt(1, 1);  }  if(typeof(x) == 'string') {    return bigint_from_string(x);  }  if(typeof(x) == 'number') {    var i, x1, x2, fpt, np;    if(-2147483647 <= x && x <= 2147483647) {      return bigint_from_int(x);    }    x = x + '';    i = x.indexOf('e', 0);    if(i == -1)      return bigint_from_string(x);    x1 = x.substr(0, i);    x2 = x.substr(i+2, x.length - (i+2));    fpt = x1.indexOf('.', 0);    if(fpt != -1) {      np = x1.length - (fpt+1);      x1 = x1.substr(0, fpt) + x1.substr(fpt+1, np);      x2 = parseInt(x2) - np;    } else {      x2 = parseInt(x2);    }    while(x2-- > 0) {      x1 += '0';    }    return bigint_from_string(x1);  }  return BigInt(1, 1);}function bigint_uminus(x){  var z = x.clone();  z.sign = !z.sign;  return bigint_norm(z);}function bigint_add_internal(x, y, sign){  var z;  var num;  var i, len;  sign = (sign == y.sign);  if (x.sign != sign) {    if (sign)      return bigint_sub_internal(y, x);    return bigint_sub_internal(x, y);  }  if (x.len > y.len) {    len = x.len + 1;    z = x; x = y; y = z;  } else {    len = y.len + 1;  }  z = new BigInt(len, sign);  len = x.len;  for (i = 0, num = 0; i < len; i++) {    num += x.digits[i] + y.digits[i];    z.digits[i] = (num & 0xffff);    num >>>= 16;  }  len = y.len;  while (num && i < len) {    num += y.digits[i];    z.digits[i++] = (num & 0xffff);    num >>>= 16;  }  while (i < len) {    z.digits[i] = y.digits[i];    i++;  }  z.digits[i] = (num & 0xffff);  return bigint_norm(z);  //  return z;}function bigint_sub_internal(x, y){  var z = 0;  var zds;  var num;  var i;  i = x.len;  // if x is larger than y, swap  if (x.len < y.len) {    z = x; x = y; y = z; // swap x y  }  else if (x.len == y.len) {    while (i > 0) {      i--;      if (x.digits[i] > y.digits[i]) { break;      }      if (x.digits[i] < y.digits[i]) { z = x; x = y; y = z; // swap x y break;      }    }  }  z = new BigInt(x.len, (z == 0) ? 1 : 0);  zds = z.digits;  for (i = 0, num = 0; i < y.len; i++) {     num += x.digits[i] - y.digits[i];    zds[i] = (num & 0xffff);    num >>>= 16;  }   while (num && i < x.len) {    num += x.digits[i];    zds[i++] = (num & 0xffff);    num >>>= 16;  }  while (i < x.len) {    zds[i] = x.digits[i];    i++;  }      return bigint_norm(z);}function bigint_plus(x, y){  x = bigint_from_any(x);  y = bigint_from_any(y);  return bigint_add_internal(x, y, 1);}function bigint_minus(x, y){  x = bigint_from_any(x);  y = bigint_from_any(y);  return bigint_add_internal(x, y, 0);}function bigint_mul(x, y){  var i, j;  var n = 0;  var z;  var zds, xds, yds;  var dd, ee;  var ylen;  x = bigint_from_any(x);  y = bigint_from_any(y);  j = x.len + y.len + 1;  z = new BigInt(j, x.sign == y.sign);  xds = x.digits;  yds = y.digits;  zds = z.digits;  ylen = y.len;  while (j--)    zds[j] = 0;  for (i = 0; i < x.len; i++) {    dd = xds[i];     if (dd == 0)      continue;    n = 0;    for (j = 0; j < ylen; j++) {      ee = n + dd * yds[j];      n = zds[i + j] + ee;      if (ee) zds[i + j] = (n & 0xffff);      n >>>= 16;    }    if (n) {      zds[i + j] = n;    }  }  return bigint_norm(z);}function bigint_divmod(x, y, modulo){  var nx = x.len;  var ny = y.len;  var i, j;  var yy, z;  var xds, yds, zds, tds;  var t2;  var num;  var dd, q;  var ee;  var mod, div;  yds = y.digits;  if (ny == 0 && yds[0] == 0)    return null; // Division by zero  if (nx < ny || nx == ny && x.digits[nx - 1] < y.digits[ny - 1]) {    if (modulo)      return bigint_norm(x);    return BigInt(1, 1);  }  xds = x.digits;  if (ny == 1) {    dd = yds[0];    z = x.clone();    zds = z.digits;    t2 = 0;    i = nx;    while (i--) {      t2 = t2 * 65536 + zds[i];      zds[i] = (t2 / dd) & 0xffff;      t2 %= dd;    }    z.sign = (x.sign == y.sign);    if (modulo) {      if (!x.sign) t2 = -t2;      if (x.sign != y.sign) { t2 = t2 + yds[0] * (y.sign ? 1 : -1);      }      return bigint_from_int(t2);    }    return bigint_norm(z);  }  z = new BigInt(nx == ny ? nx + 2 : nx + 1, x.sign == y.sign);  zds = z.digits;  if (nx == ny)    zds[nx + 1] = 0;  while (!yds[ny - 1])    ny--;  if ((dd = ((65536/(yds[ny-1]+1)) & 0xffff)) != 1) {    yy = y.clone();    tds = yy.digits;    j = 0;    num = 0;    while (j>= 16;    }    yds = tds;    j = 0;    num = 0;    while (j>= 16;    }    zds[j] = num & 0xffff;  }  else {    zds[nx] = 0;    j = nx;    while (j--) zds[j] = xds[j];  }  j = nx==ny?nx+1:nx;  do {    if (zds[j] ==  yds[ny-1]) q = 65535;    else q = ((zds[j]*65536 + zds[j-1])/yds[ny-1]) & 0xffff;    if (q) {      i = 0; num = 0; t2 = 0;      do { // multiply and subtract t2 += yds[i] * q; ee = num - (t2 & 0xffff); num = zds[j - ny + i] + ee; if (ee) zds[j - ny + i] = num & 0xffff; num >>= 16; t2 >>>= 16;      } while (++i < ny);      num += zds[j - ny + i] - t2; // borrow from high digit; don't update      while (num) { // 'add back' required i = 0; num = 0; q--; do {  ee = num + yds[i];  num = zds[j - ny + i] + ee;  if (ee) zds[j - ny + i] = num & 0xffff;  num >>= 16; } while (++i < ny); num--;      }    }    zds[j] = q;  } while (--j >= ny);  if (modulo) { // just normalize remainder    mod = z.clone();    if (dd) {      zds = mod.digits;      t2 = 0; i = ny;      while (i--) { t2 = (t2*65536) + zds[i]; zds[i] = (t2 / dd) & 0xffff; t2 %= dd;      }    }    mod.len = ny;    mod.sign = x.sign;    if (x.sign != y.sign) {      return bigint_add_internal(mod, y, 1);    }    return bigint_norm(mod);  }  div = z.clone();  zds = div.digits;  j = (nx==ny ? nx+2 : nx+1) - ny;  for (i = 0;i < j;i++) zds[i] = zds[i+ny];  div.len = i;  return bigint_norm(div);}function bigint_div(x, y){  x = bigint_from_any(x);  y = bigint_from_any(y);  return bigint_divmod(x, y, 0);}function bigint_mod(x, y){  x = bigint_from_any(x);  y = bigint_from_any(y);  return bigint_divmod(x, y, 1);}function bigint_cmp(x, y){  var xlen;  if(x == y)    return 0; // Same object  x = bigint_from_any(x);  y = bigint_from_any(y);  xlen = x.len;  if(x.sign != y.sign) {    if(x.sign)      return 1;    return -1;  }  if (xlen < y.len)    return (x.sign) ? -1 : 1;  if (xlen > y.len)    return (x.sign) ? 1 : -1;  while(xlen-- && (x.digits[xlen] == y.digits[xlen]))    ;  if (-1 == xlen)    return 0;  return (x.digits[xlen] > y.digits[xlen]) ?    (x.sign ? 1 : -1) :    (x.sign ? -1 : 1);}function bigint_number(x){  var d = 0.0;  var i = x.len;  var ds = x.digits;  while (i--) {    d = ds[i] + 65536.0 * d;  }  if (!x.sign) d = -d;  return d;}

4

我们添加一个新的按钮子程序,定义被累加数和起始累加数为文本型,利用脚本组件的计算表达式功能来实现累加,同时定义起始累加数变量为30位的整数,计算结果依然位正常累加结果.详细代码:.版本 2.支持库 script.支持库 spec.子程序 _按钮2_被单击.局部变量 被累加数, 文本型.局部变量 起始累加数, 文本型.局部变量 a, 整数型起始累加数 = “100000”.计次循环首 (100, a)    被累加数 = 脚本组件1.计算表达式 (#js大数运算 + “;var dwa= new BigInt(” + 起始累加数 + “);var dwb=new BigInt(” + #引号 + 到文本 (a) + #引号 + “); var dwc=bigint_plus(dwa, dwb);dwc;”) + #换行符    调试输出 (被累加数).计次循环尾 ()

注意事项

注意最后变量为文本型操作

推荐信息