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
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353