js 超过30位数的加减乘除运算
/*
** 说明: 计算器类,共有五个方法 加 减 乘 除 次方。 可计算超大数据
- 使用方法
- 建立计算器对象,计算结果可达千位
- var calculator=new Calculator();
- 方法
- calculator.plus(a,b);//计算两个数的和
- calculator.minus(a,b);//返回两个数的差
- calculator.multiply(a,b);//返回两个数的积
- calculator.divide(a,b,fix);//返回两个数的商,fix是保留的小数位
- calculator.power(a,b);//返回a的b次方
*/
function Calculator() {
this.numRegExp = /^-?\d+.?\d*$/
}
window.Calculator = new Calculator();
Calculator.prototype.plus = function (a, b) {
a = '' + a;
b = '' + b;
if (!this.numRegExp.test(a)) {
alert(a + '不是一个数字');
return ''
}
if (!this.numRegExp.test(b)) {
alert(b + '不是一个数字');
return ''
}
if (a.charAt(0) == '-' && b.charAt(0) != '-') {
a = a.substring(1);
return this.minus(b, a)
} else if (a.charAt(0) == '-' && b.charAt(0) == '-') {
a = a.substring(1);
b = b.substring(1);
return '-' + this.plus(a, b);
return this.minus(b, a)
} else if (a.charAt(0) != '-' && b.charAt(0) == '-') {
b = b.substring(1);
return this.minus(a, b)
} else if (a.charAt(0) != '-' && b.charAt(0) != '-') {
var c = 0;
var d = a.indexOf('.');
var e = b.indexOf('.');
var f = a.split('').reverse();
var g = b.split('').reverse();
if (d == -1 && e == -1) { } else if (d != -1 && e == -1) {
var h = c = a.length - d - 1;
f.splice(h, 1);
for (var i = 0; i < c; i++) {
g.unshift(0)
}
} else if (d == -1 && e != -1) {
var j = c = b.length - e - 1;
g.splice(j, 1);
for (var i = 0; i < c; i++) {
f.unshift(0)
}
} else if (d != -1 && e != -1) {
var h = a.length - d - 1;
var j = b.length - e - 1;
f.splice(h, 1);
g.splice(j, 1);
if (h > j) {
c = h;
for (var i = 0; i < h - j; i++) {
g.unshift(0)
}
} else {
c = j;
for (var i = 0; i < j - h; i++) {
f.unshift(0)
}
}
}
var k = this.tosingle(this.arrplus([f, g]));
var l = c - k.length + 1;
if (l > 0) {
for (var i = 0; i < l; i++) {
k.push(0)
}
}
if (c) {
k.splice(c, 0, '.');
var t = 0;
for (var i = 0; i < c; i++) {
if (!k[0]) {
k.shift();
t++
} else {
break
}
}
if (t == c) {
k.shift()
}
}
k.reverse();
let result = k.join('');
if (result == '') {
return 0
} else {
return result
}
}
}
Calculator.prototype.minus = function (a, b) {
a = '' + a;
b = '' + b;
if (!this.numRegExp.test(a)) {
alert(a + '不是一个数字');
return ''
}
if (!this.numRegExp.test(b)) {
alert(b + '不是一个数字');
return ''
}
if (a.charAt(0) == '-' && b.charAt(0) != '-') {
a = a.substring(1);
return '-' + this.plus(a, b)
} else if (a.charAt(0) == '-' && b.charAt(0) == '-') {
a = a.substring(1);
b = b.substring(1);
return this.minus(b, a)
} else if (a.charAt(0) != '-' && b.charAt(0) == '-') {
b = b.substring(1);
return this.plus(a, b)
} else if (a.charAt(0) != '-' && b.charAt(0) != '-') {
var c = 0;
var d = a.indexOf('.');
var e = b.indexOf('.');
var f = a.split('').reverse();
var g = b.split('').reverse();
if (d == -1 && e == -1) { } else if (d != -1 && e == -1) {
var h = c = a.length - d - 1;
f.splice(h, 1);
for (var i = 0; i < c; i++) {
g.unshift(0)
}
} else if (d == -1 && e != -1) {
var j = c = b.length - e - 1;
g.splice(j, 1);
for (var i = 0; i < c; i++) {
f.unshift(0)
}
} else if (d != -1 && e != -1) {
var h = a.length - d - 1;
var j = b.length - e - 1;
f.splice(h, 1);
g.splice(j, 1);
if (h > j) {
c = h;
for (var i = 0; i < h - j; i++) {
g.unshift(0)
}
} else {
c = j;
for (var i = 0; i < j - h; i++) {
f.unshift(0)
}
}
}
var k;
var z = this.contrast(f, g);
if (z) {
k = this.arrminute(f, g)
} else {
k = this.arrminute(g, f)
}
var l = c - k.length + 1;
if (l > 0) {
for (var i = 0; i < l; i++) {
k.push(0)
}
}
if (c) {
k.splice(c, 0, '.');
var t = 0;
for (var i = 0; i < c; i++) {
if (!k[0]) {
k.shift();
t++
} else {
break
}
}
if (t == c) {
k.shift()
}
}
k.reverse();
let result = k.join('');
if (!z) {
result = '-' + result
}
if (result == '') {
return 0
} else {
return result
}
}
}
Calculator.prototype.multiply = function (a, b) {
a = '' + a;
b = '' + b;
if (!this.numRegExp.test(a)) {
alert(a + '不是一个数字');
return ''
}
if (!this.numRegExp.test(b)) {
alert(b + '不是一个数字');
return ''
}
var c = 1;
if (a.charAt(0) == '-') {
a = a.substring(1);
c *= -1
}
if (b.charAt(0) == '-') {
b = b.substring(1);
c *= -1
}
var d = 0;
var e = a.indexOf('.');
var f = b.indexOf('.');
var g = a.split('').reverse();
var h = b.split('').reverse();
if (e != -1) {
var k = a.length - e - 1;
d += k;
g.splice(k, 1)
}
if (f != -1) {
var l = b.length - f - 1;
d += l;
h.splice(l, 1)
}
var m = [];
for (var i = 0; i < h.length; i++) {
var n = [];
for (var j = 0; j < i; j++) {
n.push(0)
}
for (var j = 0; j < g.length; j++) {
n.push(h[i] * g[j])
}
m.push(this.tosingle(n))
}
var o = this.tosingle(this.arrplus(m));
var p = d - o.length + 1;
if (p > 0) {
for (var i = 0; i < p; i++) {
o.push(0)
}
}
if (d) {
o.splice(d, 0, '.');
var t = 0;
for (var i = 0; i < d; i++) {
if (!o[0]) {
o.shift();
t++
} else {
break
}
}
if (t == d) {
o.shift()
}
}
o.reverse();
let result = o.join('');
if (c == -1) {
result = '-' + result
}
if (result == '') {
return 0
} else {
return result
}
}
Calculator.prototype.divide = function (a, b, c) {
a = '' + a;
b = '' + b;
if (!this.numRegExp.test(a)) {
alert(a + '不是一个数字');
return ''
}
if (!this.numRegExp.test(b)) {
alert(b + '不是一个数字');
return ''
}
var d = 1;
if (a.charAt(0) == '-') {
a = a.substring(1);
d *= -1
}
if (b.charAt(0) == '-') {
b = b.substring(1);
d *= -1
}
var e = 0;
var f = a.indexOf('.');
var g = b.indexOf('.');
var h = a.split('').reverse();
var j = b.split('').reverse();
if (f != -1) {
var k = a.length - f - 1;
e += k;
h.splice(k, 1)
}
if (g != -1) {
var l = b.length - g - 1;
e -= l;
j.splice(l, 1)
}
var m = [];
var n = c || Number(c) == 0 ? Number(c) : 10;
fixtab = e >= n ? 0 : n - e;
e += fixtab;
for (var i = 0; i < fixtab; i++) {
h.unshift(0)
}
var o = true;
while (o) {
var p = h.length;
var q = j.length;
if (p > q) {
var t = p - q;
var r = [];
if (Number(h[p - 1]) > Number(j[q - 1])) {
for (var i = 0; i < t; i++) {
r.push(0)
}
r.push(1)
} else {
for (var i = 0; i < t - 1; i++) {
r.push(0)
}
r.push(1)
}
m.push(r);
var s = r.slice(0, r.length - 1).concat(j);
h = this.tosingle2(this.arrminute(h, s))
} else if (p == q) {
var u = 0;
for (var i = 0; i < p; i++) {
if (h[p - 1 - i] > j[q - 1 - i]) {
m.push([1]);
h = this.tosingle2(this.arrminute(h, j));
break
} else if (h[p - 1 - i] == j[q - 1 - i]) {
u++
} else if (h[p - 1 - i] < j[q - 1 - i]) {
o = false;
m.push([0]);
break
}
}
if (u == p) {
m.push([1]);
h = this.tosingle2(this.arrminute(h, j));
o = false
}
} else if (p < q) {
m.push([0]);
o = false
}
}
var v = this.tosingle2(this.arrplus(m));
var w = e - v.length + 1;
if (w > 0) {
for (var i = 0; i < w; i++) {
v.push(0)
}
}
if (e) {
v.splice(e, 0, '.');
var t = 0;
for (var i = 0; i < e; i++) {
if (!v[0]) {
v.shift();
t++
} else {
break
}
}
if (t == e) {
v.shift()
}
}
v.reverse();
let result = v.join('');
if (d == -1) {
result = '-' + result
}
if (result == '') {
return 0
} else {
return result
}
}
Calculator.prototype.power = function (a, b) {
a = '' + a;
b = '' + b;
if (!this.numRegExp.test(a)) {
alert(a + '不是一个数字');
return ''
}
if (!/^\d+$/.test(b)) {
alert(b + '不是一个正整数');
return ''
}
b = Number(b);
var c = [1];
var d = {
1: a
};
if (b == 0) {
return 1
}
do {
var t = b - c[0];
for (var i = 0; i < c.length; i++) {
if (t >= c[i]) {
var e = c[0] + c[i];
d[e] = this.multiply(d[c[0]], d[c[i]]);
c.unshift(e);
break
}
}
} while (b != c[0]);
if (b == c[0]) {
return d[c[0]]
}
};
function w(a) {
var b = a.slice(0);
b.reverse();
return b.join('')
}
Calculator.prototype.sqr = function (a, b) {
alert('暂不支持开方');
return;
a = '' + a;
if (!this.numRegExp.test(a)) {
alert(a + '不是一个数字');
return ''
}
if (/^-/g.test(a)) {
alert(a + '不是一个正数');
return ''
}
var b = b || 0;
var c = a.indexOf('.');
var d = a.split('').reverse();
var e;
var f = 0;
if (c != -1) {
var g = a.length - c - 1;
d.splice(g, 1);
e = Math.ceil(g / 2) > b ? Math.ceil(g / 2) : b;
f = e * 2 - g
} else {
e = b;
f = e * 2
}
var h;
do {
h = d.pop()
} while (h == 0);
h && d.push(h);
var k = Math.ceil(d.length / 2);
var l = [];
for (var i = 0; i < k; i++) {
l.push('0')
}
var m = [0];
var n = d;
for (var i = k - 1; i > -1; i--) {
console.log('开始测试第' + i + '位');
console.log('当前平方值' + w(m));
n = this.tosingle2(this.arrminute(d, m));
console.log('还差' + w(n));
if (n.length == 0) {
for (var j = 0; j < i; j++) {
l[j] = 0
}
break
}
var o = l.slice(0);
var t = 5;
console.log('此位先写个5');
var p = 0;
console.log('定义数字增减方向');
for (; ;) {
o[i] = t;
var q = [o[i]];
for (var j = 0; j < i; j++) {
q.unshift('0')
}
console.log('增加的数字为' + w(q));
var r = this.arrMul(this.arrplus([l, o]), q);
console.log('增加的平方值为' + w(r));
var s = '';
if (p == 0) {
s = '没定义方向'
} else if (p == -1) {
s = '减向'
} else if (p == 1) {
s = '加向'
}
console.log('之前的dir方向为' + s);
if (this.contrast(n, r)) {
console.log(w(n) + '>=' + w(r));
if (p && p == -1) {
break
}
t++;
p = 1
} else {
console.log(w(n) + '<' + w(r));
t--;
if (p && p == 1) {
break
}
p = -1
}
}
l[i] = t;
m = this.tosingle(this.arrMul(l, l))
}
l.splice(e, 0, '.');
l.reverse();
return l.join('')
};
Calculator.prototype.arrMul = function (a, b) {
var c = [];
for (var i = 0; i < a.length; i++) {
var d = [];
for (var j = 0; j < i; j++) {
d.push(0)
}
for (var j = 0; j < a.length; j++) {
d.push(b[i] * a[j])
}
c.push(this.tosingle(d))
}
return this.tosingle(this.arrplus(c))
};
Calculator.prototype.tosingle = function (a) {
var b = [];
var c = 0;
for (var i = 0; i < a.length; i++) {
b.push((a[i] + c) % 10);
c = parseInt((a[i] + c) / 10)
}
while (c > 9) {
b.push(c % 10);
c = parseInt(c / 10)
}
if (c != 0) b.push(c);
return b
};
Calculator.prototype.arrplus = function (a) {
var b = [];
var c = 0;
var d = a.length;
var e = 0;
while (e < d) {
var f = 0;
e = 0;
for (var i = 0; i < d; i++) {
if (!a[i][c] && a[i][c] != 0) e++;
f += a[i][c] ? Number(a[i][c]) : 0
}
if (e < d) b.push(f);
c++
}
return b
}
Calculator.prototype.tosingle2 = function (a) {
var b = [];
var c = 0;
for (var i = 0; i < a.length; i++) {
var d = a[i] + c;
if (d >= 0) {
b.push(d % 10);
c = parseInt(d / 10)
} else {
if (d % 10 == 0) {
b.push(d % 10);
c = parseInt(d / 10)
} else {
b.push(10 + (d % 10));
c = parseInt((d / 10) - 1)
}
}
}
while (c > 9 || c < -9) {
var d = a[i] + c;
if (d >= 0) {
b.push(d % 10);
c = parseInt(d / 10)
} else {
if (d % 10 == 0) {
b.push(d % 10);
c = parseInt(d / 10)
} else {
b.push(10 + (d % 10));
c = parseInt((d / 10) - 1)
}
}
}
if (c != 0) b.push(c);
while (b[b.length - 1] == 0) {
b.pop()
}
return b
}
Calculator.prototype.arrminute = function (c, d) {
var e = [];
var f = c.length > d.length ? c.length : d.length;
for (var i = 0; i < f; i++) {
if (!c[i] && c[i] != 0) {
var a = 0
} else {
var a = Number(c[i])
}
if (!d[i] && d[i] != 0) {
var b = 0
} else {
var b = Number(d[i])
}
e.push(a - b)
}
return this.tosingle2(e)
}
Calculator.prototype.contrast = function (a, b) {
var c = a.length;
var d = b.length;
if (c < d) {
return false
} else if (c == d) {
for (var i = c - 1; i > -1; i--) {
if (Number(a[i]) < Number(b[i])) {
return false
} else if (Number(a[i]) > Number(b[i])) {
return true
}
}
}
return true
}