几个JavaScript版本的大整数运算库(转载)

转载的一个哥们儿的 留下链接 http://www.cnitblog.com/yemoo/archive/2007/10/10/34623.html

大整数运算一般用于密钥计算中。下面是作者从google过来的四个运算库。

http://www.onicos.com/staff/iz/amuse/javascript/expert/BigInt.txt

ps:这个在使用减法是时候有点问题

// var a = new BigInt(’10000000000000000′);
// var b = new BigInt(’1′);

a-b结果为10000004294967295,所以该方法还有待改进
这是比较早期的一个 JavaScript 版本的大数运算库,由日本高手出雲所作,其中只包含了加减乘除、模(求余)和比较运算。

http://www.faireal.net/demo/bigint0.5/beta28/
这是另一个日本高手的作品,这个库中包含的功能非常全,它的历史可以参见该文。

http://www.leemon.com/crypto/BigInt.js
这个是美国高手 Leemon Baird 的作品,所实现的功能也非常全。

http://www.ohdave.com/rsa/BigInt.js
最后这个来自 dave 的 RSA In JavaScript 网站,这个虽然功能没有前两个强大,但是使用比较方便,做一般的浏览器端加密部分已经够用了。

添加一个新的运算库:

 /*
 Copyright (c) 2012 Daniel Trebbien and other contributors
Portions Copyright (c) 2003 STZ-IDA and PTV AG, Karlsruhe, Germany
Portions Copyright (c) 1995-2001 International Business Machines Corporation and others

All rights reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, provided that the above copyright notice(s) and this permission notice appear in all copies of the Software and that both the above copyright notice(s) and this permission notice appear in supporting documentation.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

Except as contained in this notice, the name of a copyright holder shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization of the copyright holder.
*/
(function() {
    var m, h = function() {
        this.form = this.digits = 0;
        this.lostDigits = !1;
        this.roundingMode = 0;
        var a = this.DEFAULT_FORM,
        b = this.DEFAULT_LOSTDIGITS,
        c = this.DEFAULT_ROUNDINGMODE;
        if (4 == h.arguments.length) a = h.arguments[1],
        b = h.arguments[2],
        c = h.arguments[3];
        else if (3 == h.arguments.length) a = h.arguments[1],
        b = h.arguments[2];
        else if (2 == h.arguments.length) a = h.arguments[1];
        else if (1 != h.arguments.length) throw "MathContext(): " + h.arguments.length + " arguments given; expected 1 to 4";
        var d = h.arguments[0];
        if (d != this.DEFAULT_DIGITS) {
            if (d < this.MIN_DIGITS) throw "MathContext(): Digits too small: " + d;
            if (d > this.MAX_DIGITS) throw "MathContext(): Digits too large: " + d;
        }
        if (a != this.SCIENTIFIC && a != this.ENGINEERING && a != this.PLAIN) throw "MathContext() Bad form value: " + a;
        if (!this.isValidRound(c)) throw "MathContext(): Bad roundingMode value: " + c;
        this.digits = d;
        this.form = a;
        this.lostDigits = b;
        this.roundingMode = c
    };
    h.prototype.getDigits = function() {
        return this.digits
    };
    h.prototype.getForm = function() {
        return this.form
    };
    h.prototype.getLostDigits = function() {
        return this.lostDigits
    };
    h.prototype.getRoundingMode = function() {
        return this.roundingMode
    };
    h.prototype.toString = function() {
        var a = null,
        b = 0,
        c = null,
        a = this.form == this.SCIENTIFIC ? "SCIENTIFIC": this.form == this.ENGINEERING ? "ENGINEERING": "PLAIN",
        d = this.ROUNDS.length,
        b = 0;
        a: for (; 0 < d; d--, b++) if (this.roundingMode == this.ROUNDS[b]) {
            c = this.ROUNDWORDS[b];
            break a
        }
        return "digits=" + this.digits + " form=" + a + " lostDigits=" + (this.lostDigits ? "1": "0") + " roundingMode=" + c
    };
    h.prototype.isValidRound = function(a) {
        var b = 0,
        c = this.ROUNDS.length,
        b = 0;
        for (; 0 < c; c--, b++) if (a == this.ROUNDS[b]) return ! 0;
        return ! 1
    };
    h.prototype.PLAIN = 0;
    h.prototype.SCIENTIFIC = 1;
    h.prototype.ENGINEERING = 2;
    h.prototype.ROUND_CEILING = 2;
    h.prototype.ROUND_DOWN = 1;
    h.prototype.ROUND_FLOOR = 3;
    h.prototype.ROUND_HALF_DOWN = 5;
    h.prototype.ROUND_HALF_EVEN = 6;
    h.prototype.ROUND_HALF_UP = 4;
    h.prototype.ROUND_UNNECESSARY = 7;
    h.prototype.ROUND_UP = 0;
    h.prototype.DEFAULT_FORM = h.prototype.SCIENTIFIC;
    h.prototype.DEFAULT_DIGITS = 9;
    h.prototype.DEFAULT_LOSTDIGITS = !1;
    h.prototype.DEFAULT_ROUNDINGMODE = h.prototype.ROUND_HALF_UP;
    h.prototype.MIN_DIGITS = 0;
    h.prototype.MAX_DIGITS = 999999999;
    h.prototype.ROUNDS = [h.prototype.ROUND_HALF_UP, h.prototype.ROUND_UNNECESSARY, h.prototype.ROUND_CEILING, h.prototype.ROUND_DOWN, h.prototype.ROUND_FLOOR, h.prototype.ROUND_HALF_DOWN, h.prototype.ROUND_HALF_EVEN, h.prototype.ROUND_UP];
    h.prototype.ROUNDWORDS = "ROUND_HALF_UP ROUND_UNNECESSARY ROUND_CEILING ROUND_DOWN ROUND_FLOOR ROUND_HALF_DOWN ROUND_HALF_EVEN ROUND_UP".split(" ");
    h.prototype.DEFAULT = new h(h.prototype.DEFAULT_DIGITS, h.prototype.DEFAULT_FORM, h.prototype.DEFAULT_LOSTDIGITS, h.prototype.DEFAULT_ROUNDINGMODE);
    m = h;
    var u, F = function(a, b) {
        return (a - a % b) / b
    },
    J = function(a) {
        var b = Array(a),
        c;
        for (c = 0; c < a; ++c) b[c] = 0;
        return b
    },
    l = function() {
        this.ind = 0;
        this.form = m.prototype.PLAIN;
        this.mant = null;
        this.exp = 0;
        if (0 != l.arguments.length) {
            var a, b, c;
            1 == l.arguments.length ? (a = l.arguments[0], b = 0, c = a.length) : (a = l.arguments[0], b = l.arguments[1], c = l.arguments[2]);
            "string" == typeof a && (a = a.split(""));
            var d, e, i, f, g, j = 0,
            k = 0;
            e = !1;
            var h = k = k = j = 0,
            p = 0;
            f = 0;
            0 >= c && this.bad("BigDecimal(): ", a);
            this.ind = this.ispos;
            "-" == a[0] ? (c--, 0 == c && this.bad("BigDecimal(): ", a), this.ind = this.isneg, b++) : "+" == a[0] && (c--, 0 == c && this.bad("BigDecimal(): ", a), b++);
            e = d = !1;
            i = 0;
            g = f = -1;
            h = c;
            j = b;
            a: for (; 0 < h; h--, j++) {
                k = a[j];
                if ("0" <= k && "9" >= k) {
                    g = j;
                    i++;
                    continue a
                }
                if ("." == k) {
                    0 <= f && this.bad("BigDecimal(): ", a);
                    f = j - b;
                    continue a
                }
                if ("e" != k && "E" != k) { ("0" > k || "9" < k) && this.bad("BigDecimal(): ", a);
                    d = !0;
                    g = j;
                    i++;
                    continue a
                }
                j - b > c - 2 && this.bad("BigDecimal(): ", a);
                e = !1;
                "-" == a[j + 1] ? (e = !0, j += 2) : j = "+" == a[j + 1] ? j + 2 : j + 1;
                k = c - (j - b); (0 == k || 9 < k) && this.bad("BigDecimal(): ", a);
                c = k;
                k = j;
                for (; 0 < c; c--, k++) h = a[k],
                "0" > h && this.bad("BigDecimal(): ", a),
                "9" < h ? this.bad("BigDecimal(): ", a) : p = h - 0,
                this.exp = 10 * this.exp + p;
                e && (this.exp = -this.exp);
                e = !0;
                break a
            }
            0 == i && this.bad("BigDecimal(): ", a);
            0 <= f && (this.exp = this.exp + f - i);
            p = g - 1;
            j = b;
            a: for (; j <= p; j++) if (k = a[j], "0" == k) b++,
            f--,
            i--;
            else if ("." == k) b++,
            f--;
            else break a;
            this.mant = Array(i);
            k = b;
            if (d) {
                b = i;
                j = 0;
                for (; 0 < b; b--, j++) j == f && k++,
                h = a[k],
                "9" >= h ? this.mant[j] = h - 0 : this.bad("BigDecimal(): ", a),
                k++
            } else {
                b = i;
                j = 0;
                for (; 0 < b; b--, j++) j == f && k++,
                this.mant[j] = a[k] - 0,
                k++
            }
            if (0 == this.mant[0]) {
                if (this.ind = this.iszero, 0 < this.exp && (this.exp = 0), e) this.mant = this.ZERO.mant,
                this.exp = 0
            } else e && (this.form = m.prototype.SCIENTIFIC, f = this.exp + this.mant.length - 1, (f < this.MinExp || f > this.MaxExp) && this.bad("BigDecimal(): ", a))
        }
    },
    G = function() {
        var a;
        if (1 == G.arguments.length) a = G.arguments[0];
        else if (0 == G.arguments.length) a = this.plainMC;
        else throw "abs(): " + G.arguments.length + " arguments given; expected 0 or 1";
        return this.ind == this.isneg ? this.negate(a) : this.plus(a)
    },
    v = function() {
        var a;
        if (2 == v.arguments.length) a = v.arguments[1];
        else if (1 == v.arguments.length) a = this.plainMC;
        else throw "add(): " + v.arguments.length + " arguments given; expected 1 or 2";
        var b = v.arguments[0],
        c,
        d,
        e,
        i,
        f,
        g,
        j,
        k = 0;
        d = k = 0;
        var k = null,
        h = k = 0,
        p = 0,
        s = 0,
        r = 0,
        n = 0;
        a.lostDigits && this.checkdigits(b, a.digits);
        c = this;
        if (0 == c.ind && a.form != m.prototype.PLAIN) return b.plus(a);
        if (0 == b.ind && a.form != m.prototype.PLAIN) return c.plus(a);
        d = a.digits;
        0 < d && (c.mant.length > d && (c = this.clone(c).round(a)), b.mant.length > d && (b = this.clone(b).round(a)));
        e = new l;
        i = c.mant;
        f = c.mant.length;
        g = b.mant;
        j = b.mant.length;
        if (c.exp == b.exp) e.exp = c.exp;
        else if (c.exp > b.exp) {
            k = f + c.exp - b.exp;
            if (k >= j + d + 1 && 0 < d) return e.mant = i,
            e.exp = c.exp,
            e.ind = c.ind,
            f < d && (e.mant = this.extend(c.mant, d), e.exp -= d - f),
            e.finish(a, !1);
            e.exp = b.exp;
            k > d + 1 && 0 < d && (k = k - d - 1, j -= k, e.exp += k, k = d + 1);
            k > f && (f = k)
        } else {
            k = j + b.exp - c.exp;
            if (k >= f + d + 1 && 0 < d) return e.mant = g,
            e.exp = b.exp,
            e.ind = b.ind,
            j < d && (e.mant = this.extend(b.mant, d), e.exp -= d - j),
            e.finish(a, !1);
            e.exp = c.exp;
            k > d + 1 && 0 < d && (k = k - d - 1, f -= k, e.exp += k, k = d + 1);
            k > j && (j = k)
        }
        e.ind = c.ind == this.iszero ? this.ispos: c.ind;
        if ((c.ind == this.isneg ? 1 : 0) == (b.ind == this.isneg ? 1 : 0)) d = 1;
        else {
            do {
                d = -1;
                do
                if (b.ind != this.iszero) if (f < j || c.ind == this.iszero) k = i, i = g, g = k, k = f, f = j, j = k, e.ind = -e.ind;
                else if (! (f > j)) {
                    h = k = 0;
                    p = i.length - 1;
                    s = g.length - 1;
                    c: for (;;) {
                        if (k <= p) r = i[k];
                        else {
                            if (h > s) {
                                if (a.form != m.prototype.PLAIN) return this.ZERO;
                                break c
                            }
                            r = 0
                        }
                        n = h <= s ? g[h] : 0;
                        if (r != n) {
                            r < n && (k = i, i = g, g = k, k = f, f = j, j = k, e.ind = -e.ind);
                            break c
                        }
                        k++;
                        h++
                    }
                }
                while (0)
            } while ( 0 )
        }
        e.mant = this.byteaddsub(i, f, g, j, d, !1);
        return e.finish(a, !1)
    },
    w = function() {
        var a;
        if (2 == w.arguments.length) a = w.arguments[1];
        else if (1 == w.arguments.length) a = this.plainMC;
        else throw "compareTo(): " + w.arguments.length + " arguments given; expected 1 or 2";
        var b = w.arguments[0],
        c = 0,
        c = 0;
        a.lostDigits && this.checkdigits(b, a.digits);
        if (this.ind == b.ind && this.exp == b.exp) {
            c = this.mant.length;
            if (c < b.mant.length) return - this.ind;
            if (c > b.mant.length) return this.ind;
            if (c <= a.digits || 0 == a.digits) {
                a = c;
                c = 0;
                for (; 0 < a; a--, c++) {
                    if (this.mant[c] < b.mant[c]) return - this.ind;
                    if (this.mant[c] > b.mant[c]) return this.ind
                }
                return 0
            }
        } else {
            if (this.ind < b.ind) return - 1;
            if (this.ind > b.ind) return 1
        }
        b = this.clone(b);
        b.ind = -b.ind;
        return this.add(b, a).ind
    },
    o = function() {
        var a, b = -1;
        if (2 == o.arguments.length) a = "number" == typeof o.arguments[1] ? new m(0, m.prototype.PLAIN, !1, o.arguments[1]) : o.arguments[1];
        else if (3 == o.arguments.length) {
            b = o.arguments[1];
            if (0 > b) throw "divide(): Negative scale: " + b;
            a = new m(0, m.prototype.PLAIN, !1, o.arguments[2])
        } else if (1 == o.arguments.length) a = this.plainMC;
        else throw "divide(): " + o.arguments.length + " arguments given; expected between 1 and 3";
        return this.dodivide("D", o.arguments[0], a, b)
    },
    x = function() {
        var a;
        if (2 == x.arguments.length) a = x.arguments[1];
        else if (1 == x.arguments.length) a = this.plainMC;
        else throw "divideInteger(): " + x.arguments.length + " arguments given; expected 1 or 2";
        return this.dodivide("I", x.arguments[0], a, 0)
    },
    y = function() {
        var a;
        if (2 == y.arguments.length) a = y.arguments[1];
        else if (1 == y.arguments.length) a = this.plainMC;
        else throw "max(): " + y.arguments.length + " arguments given; expected 1 or 2";
        var b = y.arguments[0];
        return 0 <= this.compareTo(b, a) ? this.plus(a) : b.plus(a)
    },
    z = function() {
        var a;
        if (2 == z.arguments.length) a = z.arguments[1];
        else if (1 == z.arguments.length) a = this.plainMC;
        else throw "min(): " + z.arguments.length + " arguments given; expected 1 or 2";
        var b = z.arguments[0];
        return 0 >= this.compareTo(b, a) ? this.plus(a) : b.plus(a)
    },
    A = function() {
        var a;
        if (2 == A.arguments.length) a = A.arguments[1];
        else if (1 == A.arguments.length) a = this.plainMC;
        else throw "multiply(): " + A.arguments.length + " arguments given; expected 1 or 2";
        var b = A.arguments[0],
        c,
        d,
        e,
        i = e = null,
        f,
        g = 0,
        j,
        k = 0,
        h = 0;
        a.lostDigits && this.checkdigits(b, a.digits);
        c = this;
        d = 0;
        e = a.digits;
        0 < e ? (c.mant.length > e && (c = this.clone(c).round(a)), b.mant.length > e && (b = this.clone(b).round(a))) : (0 < c.exp && (d += c.exp), 0 < b.exp && (d += b.exp));
        c.mant.length < b.mant.length ? (e = c.mant, i = b.mant) : (e = b.mant, i = c.mant);
        f = e.length + i.length - 1;
        g = 9 < e[0] * i[0] ? f + 1 : f;
        j = new l;
        var g = this.createArrayWithZeros(g),
        m = e.length,
        k = 0;
        for (; 0 < m; m--, k++) h = e[k],
        0 != h && (g = this.byteaddsub(g, g.length, i, f, h, !0)),
        f--;
        j.ind = c.ind * b.ind;
        j.exp = c.exp + b.exp - d;
        j.mant = 0 == d ? g: this.extend(g, g.length + d);
        return j.finish(a, !1)
    },
    H = function() {
        var a;
        if (1 == H.arguments.length) a = H.arguments[0];
        else if (0 == H.arguments.length) a = this.plainMC;
        else throw "negate(): " + H.arguments.length + " arguments given; expected 0 or 1";
        var b;
        a.lostDigits && this.checkdigits(null, a.digits);
        b = this.clone(this);
        b.ind = -b.ind;
        return b.finish(a, !1)
    },
    I = function() {
        var a;
        if (1 == I.arguments.length) a = I.arguments[0];
        else if (0 == I.arguments.length) a = this.plainMC;
        else throw "plus(): " + I.arguments.length + " arguments given; expected 0 or 1";
        a.lostDigits && this.checkdigits(null, a.digits);
        return a.form == m.prototype.PLAIN && this.form == m.prototype.PLAIN && (this.mant.length <= a.digits || 0 == a.digits) ? this: this.clone(this).finish(a, !1)
    },
    B = function() {
        var a;
        if (2 == B.arguments.length) a = B.arguments[1];
        else if (1 == B.arguments.length) a = this.plainMC;
        else throw "pow(): " + B.arguments.length + " arguments given; expected 1 or 2";
        var b = B.arguments[0],
        c,
        d,
        e,
        i = e = 0,
        f,
        g = 0;
        a.lostDigits && this.checkdigits(b, a.digits);
        c = b.intcheck(this.MinArg, this.MaxArg);
        d = this;
        e = a.digits;
        if (0 == e) {
            if (b.ind == this.isneg) throw "pow(): Negative power: " + b.toString();
            e = 0
        } else {
            if (b.mant.length + b.exp > e) throw "pow(): Too many digits: " + b.toString();
            d.mant.length > e && (d = this.clone(d).round(a));
            i = b.mant.length + b.exp;
            e = e + i + 1
        }
        e = new m(e, a.form, !1, a.roundingMode);
        i = this.ONE;
        if (0 == c) return i;
        0 > c && (c = -c);
        f = !1;
        g = 1;
        a: for (;; g++) {
            c <<= 1;
            0 > c && (f = !0, i = i.multiply(d, e));
            if (31 == g) break a;
            if (!f) continue a;
            i = i.multiply(i, e)
        }
        0 > b.ind && (i = this.ONE.divide(i, e));
        return i.finish(a, !0)
    },
    C = function() {
        var a;
        if (2 == C.arguments.length) a = C.arguments[1];
        else if (1 == C.arguments.length) a = this.plainMC;
        else throw "remainder(): " + C.arguments.length + " arguments given; expected 1 or 2";
        return this.dodivide("R", C.arguments[0], a, -1)
    },
    D = function() {
        var a;
        if (2 == D.arguments.length) a = D.arguments[1];
        else if (1 == D.arguments.length) a = this.plainMC;
        else throw "subtract(): " + D.arguments.length + " arguments given; expected 1 or 2";
        var b = D.arguments[0];
        a.lostDigits && this.checkdigits(b, a.digits);
        b = this.clone(b);
        b.ind = -b.ind;
        return this.add(b, a)
    },
    q = function() {
        var a, b, c, d;
        if (6 == q.arguments.length) a = q.arguments[2],
        b = q.arguments[3],
        c = q.arguments[4],
        d = q.arguments[5];
        else if (2 == q.arguments.length) b = a = -1,
        c = m.prototype.SCIENTIFIC,
        d = this.ROUND_HALF_UP;
        else throw "format(): " + q.arguments.length + " arguments given; expected 2 or 6";
        var e = q.arguments[0],
        i = q.arguments[1],
        f,
        g = 0,
        g = g = 0,
        j = null,
        k = j = g = 0;
        f = 0;
        g = null;
        k = j = 0; ( - 1 > e || 0 == e) && this.badarg("format", 1, e); - 1 > i && this.badarg("format", 2, i); ( - 1 > a || 0 == a) && this.badarg("format", 3, a); - 1 > b && this.badarg("format", 4, b);
        c != m.prototype.SCIENTIFIC && c != m.prototype.ENGINEERING && ( - 1 == c ? c = m.prototype.SCIENTIFIC: this.badarg("format", 5, c));
        if (d != this.ROUND_HALF_UP) try { - 1 == d ? d = this.ROUND_HALF_UP: new m(9, m.prototype.SCIENTIFIC, !1, d)
        } catch(l) {
            this.badarg("format", 6, d)
        }
        f = this.clone(this); - 1 == b ? f.form = m.prototype.PLAIN: f.ind == this.iszero ? f.form = m.prototype.PLAIN: (g = f.exp + f.mant.length, f.form = g > b ? c: -5 > g ? c: m.prototype.PLAIN);
        if (0 <= i) a: for (;;) {
            f.form == m.prototype.PLAIN ? g = -f.exp: f.form == m.prototype.SCIENTIFIC ? g = f.mant.length - 1 : (g = (f.exp + f.mant.length - 1) % 3, 0 > g && (g = 3 + g), g++, g = g >= f.mant.length ? 0 : f.mant.length - g);
            if (g == i) break a;
            if (g < i) {
                j = this.extend(f.mant, f.mant.length + i - g);
                f.mant = j;
                f.exp -= i - g;
                if (f.exp < this.MinExp) throw "format(): Exponent Overflow: " + f.exp;
                break a
            }
            g -= i;
            if (g > f.mant.length) {
                f.mant = this.ZERO.mant;
                f.ind = this.iszero;
                f.exp = 0;
                continue a
            }
            j = f.mant.length - g;
            k = f.exp;
            f.round(j, d);
            if (f.exp - k == g) break a
        }
        b = f.layout();
        if (0 < e) {
            c = b.length;
            f = 0;
            a: for (; 0 < c; c--, f++) {
                if ("." == b[f]) break a;
                if ("E" == b[f]) break a
            }
            f > e && this.badarg("format", 1, e);
            if (f < e) {
                g = Array(b.length + e - f);
                e -= f;
                j = 0;
                for (; 0 < e; e--, j++) g[j] = " ";
                this.arraycopy(b, 0, g, j, b.length);
                b = g
            }
        }
        if (0 < a) {
            e = b.length - 1;
            f = b.length - 1;
            a: for (; 0 < e; e--, f--) if ("E" == b[f]) break a;
            if (0 == f) {
                g = Array(b.length + a + 2);
                this.arraycopy(b, 0, g, 0, b.length);
                a += 2;
                j = b.length;
                for (; 0 < a; a--, j++) g[j] = " ";
                b = g
            } else if (k = b.length - f - 2, k > a && this.badarg("format", 3, a), k < a) {
                g = Array(b.length + a - k);
                this.arraycopy(b, 0, g, 0, f + 2);
                a -= k;
                j = f + 2;
                for (; 0 < a; a--, j++) g[j] = "0";
                this.arraycopy(b, f + 2, g, j, k);
                b = g
            }
        }
        return b.join("")
    },
    E = function() {
        var a;
        if (2 == E.arguments.length) a = E.arguments[1];
        else if (1 == E.arguments.length) a = this.ROUND_UNNECESSARY;
        else throw "setScale(): " + E.arguments.length + " given; expected 1 or 2";
        var b = E.arguments[0],
        c,
        d;
        c = c = 0;
        c = this.scale();
        if (c == b && this.form == m.prototype.PLAIN) return this;
        d = this.clone(this);
        if (c <= b) c = 0 == c ? d.exp + b: b - c,
        d.mant = this.extend(d.mant, d.mant.length + c),
        d.exp = -b;
        else {
            if (0 > b) throw "setScale(): Negative scale: " + b;
            c = d.mant.length - (c - b);
            d = d.round(c, a);
            d.exp != -b && (d.mant = this.extend(d.mant, d.mant.length + 1), d.exp -= 1)
        }
        d.form = m.prototype.PLAIN;
        return d
    };
    u = function() {
        var a, b = 0,
        c = 0;
        a = Array(190);
        b = 0;
        a: for (; 189 >= b; b++) {
            c = b - 90;
            if (0 <= c) {
                a[b] = c % 10;
                l.prototype.bytecar[b] = F(c, 10);
                continue a
            }
            c += 100;
            a[b] = c % 10;
            l.prototype.bytecar[b] = F(c, 10) - 10
        }
        return a
    };
    var t = function() {
        var a, b;
        if (2 == t.arguments.length) a = t.arguments[0],
        b = t.arguments[1];
        else if (1 == t.arguments.length) b = t.arguments[0],
        a = b.digits,
        b = b.roundingMode;
        else throw "round(): " + t.arguments.length + " arguments given; expected 1 or 2";
        var c, d, e = !1,
        i = 0,
        f;
        c = null;
        c = this.mant.length - a;
        if (0 >= c) return this;
        this.exp += c;
        c = this.ind;
        d = this.mant;
        0 < a ? (this.mant = Array(a), this.arraycopy(d, 0, this.mant, 0, a), e = !0, i = d[a]) : (this.mant = this.ZERO.mant, this.ind = this.iszero, e = !1, i = 0 == a ? d[0] : 0);
        f = 0;
        if (b == this.ROUND_HALF_UP) 5 <= i && (f = c);
        else if (b == this.ROUND_UNNECESSARY) {
            if (!this.allzero(d, a)) throw "round(): Rounding necessary";
        } else if (b == this.ROUND_HALF_DOWN) 5 < i ? f = c: 5 == i && (this.allzero(d, a + 1) || (f = c));
        else if (b == this.ROUND_HALF_EVEN) 5 < i ? f = c: 5 == i && (this.allzero(d, a + 1) ? 1 == this.mant[this.mant.length - 1] % 2 && (f = c) : f = c);
        else if (b != this.ROUND_DOWN) if (b == this.ROUND_UP) this.allzero(d, a) || (f = c);
        else if (b == this.ROUND_CEILING) 0 < c && (this.allzero(d, a) || (f = c));
        else if (b == this.ROUND_FLOOR) 0 > c && (this.allzero(d, a) || (f = c));
        else throw "round(): Bad round value: " + b;
        0 != f && (this.ind == this.iszero ? (this.mant = this.ONE.mant, this.ind = f) : (this.ind == this.isneg && (f = -f), c = this.byteaddsub(this.mant, this.mant.length, this.ONE.mant, 1, f, e), c.length > this.mant.length ? (this.exp++, this.arraycopy(c, 0, this.mant, 0, this.mant.length)) : this.mant = c));
        if (this.exp > this.MaxExp) throw "round(): Exponent Overflow: " + this.exp;
        return this
    };
    l.prototype.div = F;
    l.prototype.arraycopy = function(a, b, c, d, e) {
        var i;
        if (d > b) for (i = e - 1; 0 <= i; --i) c[i + d] = a[i + b];
        else for (i = 0; i < e; ++i) c[i + d] = a[i + b]
    };
    l.prototype.createArrayWithZeros = J;
    l.prototype.abs = G;
    l.prototype.add = v;
    l.prototype.compareTo = w;
    l.prototype.divide = o;
    l.prototype.divideInteger = x;
    l.prototype.max = y;
    l.prototype.min = z;
    l.prototype.multiply = A;
    l.prototype.negate = H;
    l.prototype.plus = I;
    l.prototype.pow = B;
    l.prototype.remainder = C;
    l.prototype.subtract = D;
    l.prototype.equals = function(a) {
        var b = 0,
        c = null,
        d = null;
        if (null == a || !(a instanceof l) || this.ind != a.ind) return ! 1;
        if (this.mant.length == a.mant.length && this.exp == a.exp && this.form == a.form) {
            c = this.mant.length;
            b = 0;
            for (; 0 < c; c--, b++) if (this.mant[b] != a.mant[b]) return ! 1
        } else {
            c = this.layout();
            d = a.layout();
            if (c.length != d.length) return ! 1;
            a = c.length;
            b = 0;
            for (; 0 < a; a--, b++) if (c[b] != d[b]) return ! 1
        }
        return ! 0
    };
    l.prototype.format = q;
    l.prototype.intValueExact = function() {
        var a, b = 0,
        c, d = 0;
        a = 0;
        if (this.ind == this.iszero) return 0;
        a = this.mant.length - 1;
        if (0 > this.exp) {
            a += this.exp;
            if (!this.allzero(this.mant, a + 1)) throw "intValueExact(): Decimal part non-zero: " + this.toString();
            if (0 > a) return 0;
            b = 0
        } else {
            if (9 < this.exp + a) throw "intValueExact(): Conversion overflow: " + this.toString();
            b = this.exp
        }
        c = 0;
        var e = a + b,
        d = 0;
        for (; d <= e; d++) c *= 10,
        d <= a && (c += this.mant[d]);
        if (9 == a + b && (a = F(c, 1E9), a != this.mant[0])) {
            if ( - 2147483648 == c && this.ind == this.isneg && 2 == this.mant[0]) return c;
            throw "intValueExact(): Conversion overflow: " + this.toString();
        }
        return this.ind == this.ispos ? c: -c
    };
    l.prototype.movePointLeft = function(a) {
        var b;
        b = this.clone(this);
        b.exp -= a;
        return b.finish(this.plainMC, !1)
    };
    l.prototype.movePointRight = function(a) {
        var b;
        b = this.clone(this);
        b.exp += a;
        return b.finish(this.plainMC, !1)
    };
    l.prototype.scale = function() {
        return 0 <= this.exp ? 0 : -this.exp
    };
    l.prototype.setScale = E;
    l.prototype.signum = function() {
        return this.ind
    };
    l.prototype.toString = function() {
        return this.layout().join("")
    };
    l.prototype.layout = function() {
        var a, b = 0,
        b = null,
        c = 0,
        d = 0;
        a = 0;
        var d = null,
        e, b = 0;
        a = Array(this.mant.length);
        c = this.mant.length;
        b = 0;
        for (; 0 < c; c--, b++) a[b] = this.mant[b] + "";
        if (this.form != m.prototype.PLAIN) {
            b = "";
            this.ind == this.isneg && (b += "-");
            c = this.exp + a.length - 1;
            if (this.form == m.prototype.SCIENTIFIC) b += a[0],
            1 < a.length && (b += "."),
            b += a.slice(1).join("");
            else if (d = c % 3, 0 > d && (d = 3 + d), c -= d, d++, d >= a.length) {
                b += a.join("");
                for (a = d - a.length; 0 < a; a--) b += "0"
            } else b += a.slice(0, d).join(""),
            b = b + "." + a.slice(d).join("");
            0 != c && (0 > c ? (a = "-", c = -c) : a = "+", b = b + "E" + a + c);
            return b.split("")
        }
        if (0 == this.exp) {
            if (0 <= this.ind) return a;
            d = Array(a.length + 1);
            d[0] = "-";
            this.arraycopy(a, 0, d, 1, a.length);
            return d
        }
        c = this.ind == this.isneg ? 1 : 0;
        e = this.exp + a.length;
        if (1 > e) {
            b = c + 2 - this.exp;
            d = Array(b);
            0 != c && (d[0] = "-");
            d[c] = "0";
            d[c + 1] = ".";
            var i = -e,
            b = c + 2;
            for (; 0 < i; i--, b++) d[b] = "0";
            this.arraycopy(a, 0, d, c + 2 - e, a.length);
            return d
        }
        if (e > a.length) {
            d = Array(c + e);
            0 != c && (d[0] = "-");
            this.arraycopy(a, 0, d, c, a.length);
            e -= a.length;
            b = c + a.length;
            for (; 0 < e; e--, b++) d[b] = "0";
            return d
        }
        b = c + 1 + a.length;
        d = Array(b);
        0 != c && (d[0] = "-");
        this.arraycopy(a, 0, d, c, e);
        d[c + e] = ".";
        this.arraycopy(a, e, d, c + e + 1, a.length - e);
        return d
    };
    l.prototype.intcheck = function(a, b) {
        var c;
        c = this.intValueExact();
        if (c < a || c > b) throw "intcheck(): Conversion overflow: " + c;
        return c
    };
    l.prototype.dodivide = function(a, b, c, d) {
        var e, i, f, g, j, k, h, p, s, r = 0,
        n = 0,
        o = 0;
        i = i = n = n = n = 0;
        e = null;
        e = e = 0;
        e = null;
        c.lostDigits && this.checkdigits(b, c.digits);
        e = this;
        if (0 == b.ind) throw "dodivide(): Divide by 0";
        if (0 == e.ind) return c.form != m.prototype.PLAIN ? this.ZERO: -1 == d ? e: e.setScale(d);
        i = c.digits;
        if (0 < i) e.mant.length > i && (e = this.clone(e).round(c)),
        b.mant.length > i && (b = this.clone(b).round(c));
        else if ( - 1 == d && (d = e.scale()), i = e.mant.length, d != -e.exp && (i = i + d + e.exp), i = i - (b.mant.length - 1) - b.exp, i < e.mant.length && (i = e.mant.length), i < b.mant.length) i = b.mant.length;
        f = e.exp - b.exp + e.mant.length - b.mant.length;
        if (0 > f && "D" != a) return "I" == a ? this.ZERO: this.clone(e).finish(c, !1);
        g = new l;
        g.ind = e.ind * b.ind;
        g.exp = f;
        g.mant = this.createArrayWithZeros(i + 1);
        j = i + i + 1;
        f = this.extend(e.mant, j);
        k = j;
        h = b.mant;
        p = j;
        s = 10 * h[0] + 1;
        1 < h.length && (s += h[1]);
        j = 0;
        a: for (;;) {
            r = 0;
            b: for (;;) {
                if (k < p) break b;
                if (k == p) {
                    c: do {
                        var q = k,
                        n = 0;
                        for (; 0 < q; q--, n++) {
                            o = n < h.length ? h[n] : 0;
                            if (f[n] < o) break b;
                            if (f[n] > o) break c
                        }
                        r++;
                        g.mant[j] = r;
                        j++;
                        f[0] = 0;
                        break a
                    } while ( 0 );
                    n = f[0]
                } else n = 10 * f[0],
                1 < k && (n += f[1]);
                n = F(10 * n, s);
                0 == n && (n = 1);
                r += n;
                f = this.byteaddsub(f, k, h, p, -n, !0);
                if (0 != f[0]) continue b;
                o = k - 2;
                n = 0;
                c: for (; n <= o; n++) {
                    if (0 != f[n]) break c;
                    k--
                }
                if (0 == n) continue b;
                this.arraycopy(f, n, f, 0, k)
            }
            if (0 != j || 0 != r) {
                g.mant[j] = r;
                j++;
                if (j == i + 1) break a;
                if (0 == f[0]) break a
            }
            if (0 <= d && -g.exp > d) break a;
            if ("D" != a && 0 >= g.exp) break a;
            g.exp -= 1;
            p--
        }
        0 == j && (j = 1);
        if ("I" == a || "R" == a) {
            if (j + g.exp > i) throw "dodivide(): Integer overflow";
            if ("R" == a) {
                do {
                    if (0 == g.mant[0]) return this.clone(e).finish(c, !1);
                    if (0 == f[0]) return this.ZERO;
                    g.ind = e.ind;
                    i = i + i + 1 - e.mant.length;
                    g.exp = g.exp - i + e.exp;
                    i = k;
                    n = i - 1;
                    b: for (; 1 <= n && g.exp < e.exp && g.exp < b.exp; n--) {
                        if (0 != f[n]) break b;
                        i--;
                        g.exp += 1
                    }
                    i < f.length && (e = Array(i), this.arraycopy(f, 0, e, 0, i), f = e);
                    g.mant = f;
                    return g.finish(c, !1)
                } while ( 0 )
            }
        } else 0 != f[0] && (e = g.mant[j - 1], 0 == e % 5 && (g.mant[j - 1] = e + 1));
        if (0 <= d) return j != g.mant.length && (g.exp -= g.mant.length - j),
        e = g.mant.length - ( - g.exp - d),
        g.round(e, c.roundingMode),
        g.exp != -d && (g.mant = this.extend(g.mant, g.mant.length + 1), g.exp -= 1),
        g.finish(c, !0);
        if (j == g.mant.length) g.round(c);
        else {
            if (0 == g.mant[0]) return this.ZERO;
            e = Array(j);
            this.arraycopy(g.mant, 0, e, 0, j);
            g.mant = e
        }
        return g.finish(c, !0)
    };
    l.prototype.bad = function(a, b) {
        throw a + "Not a number: " + b;
    };
    l.prototype.badarg = function(a, b, c) {
        throw "Bad argument " + b + " to " + a + ": " + c;
    };
    l.prototype.extend = function(a, b) {
        var c;
        if (a.length == b) return a;
        c = J(b);
        this.arraycopy(a, 0, c, 0, a.length);
        return c
    };
    l.prototype.byteaddsub = function(a, b, c, d, e, i) {
        var f, g, j, k, l, h, m = 0;
        f = h = 0;
        f = a.length;
        g = c.length;
        b -= 1;
        k = j = d - 1;
        k < b && (k = b);
        d = null;
        i && k + 1 == f && (d = a);
        null == d && (d = this.createArrayWithZeros(k + 1));
        l = !1;
        1 == e ? l = !0 : -1 == e && (l = !0);
        h = 0;
        m = k;
        a: for (; 0 <= m; m--) {
            0 <= b && (b < f && (h += a[b]), b--);
            0 <= j && (j < g && (h = l ? 0 < e ? h + c[j] : h - c[j] : h + c[j] * e), j--);
            if (10 > h && 0 <= h) {
                do {
                    d[m] = h;
                    h = 0;
                    continue a
                } while ( 0 )
            }
            h += 90;
            d[m] = this.bytedig[h];
            h = this.bytecar[h]
        }
        if (0 == h) return d;
        c = null;
        i && k + 2 == a.length && (c = a);
        null == c && (c = Array(k + 2));
        c[0] = h;
        a = k + 1;
        f = 0;
        for (; 0 < a; a--, f++) c[f + 1] = d[f];
        return c
    };
    l.prototype.diginit = u;
    l.prototype.clone = function(a) {
        var b;
        b = new l;
        b.ind = a.ind;
        b.exp = a.exp;
        b.form = a.form;
        b.mant = a.mant;
        return b
    };
    l.prototype.checkdigits = function(a, b) {
        if (0 != b) {
            if (this.mant.length > b && !this.allzero(this.mant, b)) throw "Too many digits: " + this.toString();
            if (null != a && a.mant.length > b && !this.allzero(a.mant, b)) throw "Too many digits: " + a.toString();
        }
    };
    l.prototype.round = t;
    l.prototype.allzero = function(a, b) {
        var c = 0;
        0 > b && (b = 0);
        var d = a.length - 1,
        c = b;
        for (; c <= d; c++) if (0 != a[c]) return ! 1;
        return ! 0
    };
    l.prototype.finish = function(a, b) {
        var c = 0,
        d = 0,
        e = null,
        c = d = 0;
        0 != a.digits && this.mant.length > a.digits && this.round(a);
        if (b && a.form != m.prototype.PLAIN) {
            c = this.mant.length;
            d = c - 1;
            a: for (; 1 <= d; d--) {
                if (0 != this.mant[d]) break a;
                c--;
                this.exp++
            }
            c < this.mant.length && (e = Array(c), this.arraycopy(this.mant, 0, e, 0, c), this.mant = e)
        }
        this.form = m.prototype.PLAIN;
        c = this.mant.length;
        d = 0;
        for (; 0 < c; c--, d++) if (0 != this.mant[d]) {
            0 < d && (e = Array(this.mant.length - d), this.arraycopy(this.mant, d, e, 0, this.mant.length - d), this.mant = e);
            d = this.exp + this.mant.length;
            if (0 < d) {
                if (d > a.digits && 0 != a.digits && (this.form = a.form), d - 1 <= this.MaxExp) return this
            } else - 5 > d && (this.form = a.form);
            d--;
            if (d < this.MinExp || d > this.MaxExp) {
                b: do {
                    if (this.form == m.prototype.ENGINEERING && (c = d % 3, 0 > c && (c = 3 + c), d -= c, d >= this.MinExp && d <= this.MaxExp)) break b;
                    throw "finish(): Exponent Overflow: " + d;
                } while ( 0 )
            }
            return this
        }
        this.ind = this.iszero;
        if (a.form != m.prototype.PLAIN) this.exp = 0;
        else if (0 < this.exp) this.exp = 0;
        else if (this.exp < this.MinExp) throw "finish(): Exponent Overflow: " + this.exp;
        this.mant = this.ZERO.mant;
        return this
    };
    l.prototype.isGreaterThan = function(a) {
        return 0 < this.compareTo(a)
    };
    l.prototype.isLessThan = function(a) {
        return 0 > this.compareTo(a)
    };
    l.prototype.isGreaterThanOrEqualTo = function(a) {
        return 0 <= this.compareTo(a)
    };
    l.prototype.isLessThanOrEqualTo = function(a) {
        return 0 >= this.compareTo(a)
    };
    l.prototype.isPositive = function() {
        return 0 < this.compareTo(l.prototype.ZERO)
    };
    l.prototype.isNegative = function() {
        return 0 > this.compareTo(l.prototype.ZERO)
    };
    l.prototype.isZero = function() {
        return this.equals(l.prototype.ZERO)
    };
    l.prototype.ROUND_CEILING = m.prototype.ROUND_CEILING;
    l.prototype.ROUND_DOWN = m.prototype.ROUND_DOWN;
    l.prototype.ROUND_FLOOR = m.prototype.ROUND_FLOOR;
    l.prototype.ROUND_HALF_DOWN = m.prototype.ROUND_HALF_DOWN;
    l.prototype.ROUND_HALF_EVEN = m.prototype.ROUND_HALF_EVEN;
    l.prototype.ROUND_HALF_UP = m.prototype.ROUND_HALF_UP;
    l.prototype.ROUND_UNNECESSARY = m.prototype.ROUND_UNNECESSARY;
    l.prototype.ROUND_UP = m.prototype.ROUND_UP;
    l.prototype.ispos = 1;
    l.prototype.iszero = 0;
    l.prototype.isneg = -1;
    l.prototype.MinExp = -999999999;
    l.prototype.MaxExp = 999999999;
    l.prototype.MinArg = -999999999;
    l.prototype.MaxArg = 999999999;
    l.prototype.plainMC = new m(0, m.prototype.PLAIN);
    l.prototype.bytecar = Array(190);
    l.prototype.bytedig = u();
    l.prototype.ZERO = new l("0");
    l.prototype.ONE = new l("1");
    l.prototype.TEN = new l("10");
    u = l;
    "function" === typeof define && null != define.amd ? define({
        BigDecimal: u,
        MathContext: m
    }) : "object" === typeof this && (this.BigDecimal = u, this.MathContext = m)
}).call(this);

这个是使用方法:http://www.cnblogs.com/linjiqin/p/3413894.html

ps:最后一个方法挺好用,起码数据结果是正确的~

 

此条目发表在 javascript 分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*


*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>