首页 > 代码库 > javascript 大数值数据运算

javascript 大数值数据运算

javascript数字运算结果不准确:

1、浮点型数字进行运算时,基本四则运算结果都可能不准确,一般是把浮点型数据转换为整型运算,然后在还原处理。

这种情况下可以用一些常用转换方法计算,如下:

 1 /** 2  * 加法运算 3  */ 4 function numAdd(num1, num2) { 5     var baseNum, baseNum1, baseNum2; 6     try { 7         baseNum1 = num1.toString().split(".")[1].length; 8     } catch (e) { 9         baseNum1 = 0;10     }11     try {12         baseNum2 = num2.toString().split(".")[1].length;13     } catch (e) {14         baseNum2 = 0;15     }16     baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));17     return (num1 * baseNum + num2 * baseNum) / baseNum;18 };19 20 /**21  * 减法运算22  */23 function numSub(num1, num2) {24     var baseNum, baseNum1, baseNum2;25     var precision;26     //精度    27     try {28         baseNum1 = num1.toString().split(".")[1].length;29     } catch (e) {30         baseNum1 = 0;31     }32     try {33         baseNum2 = num2.toString().split(".")[1].length;34     } catch (e) {35         baseNum2 = 0;36     }37     baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));38     precision = (baseNum1 >= baseNum2) ? baseNum1 : baseNum2;39     return ((num1 * baseNum - num2 * baseNum) / baseNum).toFixed(precision);40 }41 42 /**43  * 乘法运算44  */45 function numMulti(num1, num2) {46     var baseNum = 0;47     try {48         baseNum += num1.toString().split(".")[1].length;49     } catch (e) {50     }51     try {52         baseNum += num2.toString().split(".")[1].length;53     } catch (e) {54     }55     return Number(num1.toString().replace(".", ""))56             * Number(num2.toString().replace(".", "")) / Math.pow(10, baseNum);57 };58 59 60 /**61  * 除法運算62  */63 function numDiv(num1, num2) {64     var baseNum1 = 0, baseNum2 = 0;65     var baseNum3, baseNum4;66     try {67         baseNum1 = num1.toString().split(".")[1].length;68     } catch (e) {69         baseNum1 = 0;70     }71     try {72         baseNum2 = num2.toString().split(".")[1].length;73     } catch (e) {74         baseNum2 = 0;75     }76     with (Math) {77         baseNum3 = Number(num1.toString().replace(".", ""));78         baseNum4 = Number(num2.toString().replace(".", ""));79         return (baseNum3 / baseNum4) * pow(10, baseNum2 - baseNum1);80     }81 }

 

2、整数运算在数字特别大的时候,计算结果的尾数也会不准确。如超过9个9乘以本身的乘法运算时,计算出的结果最大是999999998000000000,正常结果个位数应该为1,但是js运算结果将个位数去掉了,类似数据比较大时,经验证,7位数乘以7位数还是正常的,超过后就不准确了。网上搜到国外有个针对js计算大数值的情况,是麻省理工的专门写了大数值运算的算法。乘法运算可支持15位以内的运算。如下是js算法全文

 

 

   1 /*   2     JavaScript BigInteger library version 0.9   3     http://silentmatt.com/biginteger/   4    5     Copyright (c) 2009 Matthew Crumley <email@matthewcrumley.com>   6     Copyright (c) 2010,2011 by John Tobey <John.Tobey@gmail.com>   7     Licensed under the MIT license.   8    9     Support for arbitrary internal representation base was added by  10     Vitaly Magerya.  11 */  12   13 /*  14     File: biginteger.js  15   16     Exports:  17   18         <BigInteger>  19 */  20 (function(exports) {  21 "use strict";  22 /*  23     Class: BigInteger  24     An arbitrarily-large integer.  25   26     <BigInteger> objects should be considered immutable. None of the "built-in"  27     methods modify *this* or their arguments. All properties should be  28     considered private.  29   30     All the methods of <BigInteger> instances can be called "statically". The  31     static versions are convenient if you don‘t already have a <BigInteger>  32     object.  33   34     As an example, these calls are equivalent.  35   36     > BigInteger(4).multiply(5); // returns BigInteger(20);  37     > BigInteger.multiply(4, 5); // returns BigInteger(20);  38   39     > var a = 42;  40     > var a = BigInteger.toJSValue("0b101010"); // Not completely useless...  41 */  42   43 var CONSTRUCT = {}; // Unique token to call "private" version of constructor  44   45 /*  46     Constructor: BigInteger()  47     Convert a value to a <BigInteger>.  48   49     Although <BigInteger()> is the constructor for <BigInteger> objects, it is  50     best not to call it as a constructor. If *n* is a <BigInteger> object, it is  51     simply returned as-is. Otherwise, <BigInteger()> is equivalent to <parse>  52     without a radix argument.  53   54     > var n0 = BigInteger();      // Same as <BigInteger.ZERO>  55     > var n1 = BigInteger("123"); // Create a new <BigInteger> with value 123  56     > var n2 = BigInteger(123);   // Create a new <BigInteger> with value 123  57     > var n3 = BigInteger(n2);    // Return n2, unchanged  58   59     The constructor form only takes an array and a sign. *n* must be an  60     array of numbers in little-endian order, where each digit is between 0  61     and BigInteger.base.  The second parameter sets the sign: -1 for  62     negative, +1 for positive, or 0 for zero. The array is *not copied and  63     may be modified*. If the array contains only zeros, the sign parameter  64     is ignored and is forced to zero.  65   66     > new BigInteger([5], -1): create a new BigInteger with value -5  67   68     Parameters:  69   70         n - Value to convert to a <BigInteger>.  71   72     Returns:  73   74         A <BigInteger> value.  75   76     See Also:  77   78         <parse>, <BigInteger>  79 */  80 function BigInteger(n, s, token) {  81     if (token !== CONSTRUCT) {  82         if (n instanceof BigInteger) {  83             return n;  84         }  85         else if (typeof n === "undefined") {  86             return ZERO;  87         }  88         return BigInteger.parse(n);  89     }  90   91     n = n || [];  // Provide the nullary constructor for subclasses.  92     while (n.length && !n[n.length - 1]) {  93         --n.length;  94     }  95     this._d = n;  96     this._s = n.length ? (s || 1) : 0;  97 }  98   99 BigInteger._construct = function(n, s) { 100     return new BigInteger(n, s, CONSTRUCT); 101 }; 102  103 // Base-10 speedup hacks in parse, toString, exp10 and log functions 104 // require base to be a power of 10. 10^7 is the largest such power 105 // that won‘t cause a precision loss when digits are multiplied. 106 var BigInteger_base = 10000000; 107 var BigInteger_base_log10 = 7; 108  109 BigInteger.base = BigInteger_base; 110 BigInteger.base_log10 = BigInteger_base_log10; 111  112 var ZERO = new BigInteger([], 0, CONSTRUCT); 113 // Constant: ZERO 114 // <BigInteger> 0. 115 BigInteger.ZERO = ZERO; 116  117 var ONE = new BigInteger([1], 1, CONSTRUCT); 118 // Constant: ONE 119 // <BigInteger> 1. 120 BigInteger.ONE = ONE; 121  122 var M_ONE = new BigInteger(ONE._d, -1, CONSTRUCT); 123 // Constant: M_ONE 124 // <BigInteger> -1. 125 BigInteger.M_ONE = M_ONE; 126  127 // Constant: _0 128 // Shortcut for <ZERO>. 129 BigInteger._0 = ZERO; 130  131 // Constant: _1 132 // Shortcut for <ONE>. 133 BigInteger._1 = ONE; 134  135 /* 136     Constant: small 137     Array of <BigIntegers> from 0 to 36. 138  139     These are used internally for parsing, but useful when you need a "small" 140     <BigInteger>. 141  142     See Also: 143  144         <ZERO>, <ONE>, <_0>, <_1> 145 */ 146 BigInteger.small = [ 147     ZERO, 148     ONE, 149     /* Assuming BigInteger_base > 36 */ 150     new BigInteger( [2], 1, CONSTRUCT), 151     new BigInteger( [3], 1, CONSTRUCT), 152     new BigInteger( [4], 1, CONSTRUCT), 153     new BigInteger( [5], 1, CONSTRUCT), 154     new BigInteger( [6], 1, CONSTRUCT), 155     new BigInteger( [7], 1, CONSTRUCT), 156     new BigInteger( [8], 1, CONSTRUCT), 157     new BigInteger( [9], 1, CONSTRUCT), 158     new BigInteger([10], 1, CONSTRUCT), 159     new BigInteger([11], 1, CONSTRUCT), 160     new BigInteger([12], 1, CONSTRUCT), 161     new BigInteger([13], 1, CONSTRUCT), 162     new BigInteger([14], 1, CONSTRUCT), 163     new BigInteger([15], 1, CONSTRUCT), 164     new BigInteger([16], 1, CONSTRUCT), 165     new BigInteger([17], 1, CONSTRUCT), 166     new BigInteger([18], 1, CONSTRUCT), 167     new BigInteger([19], 1, CONSTRUCT), 168     new BigInteger([20], 1, CONSTRUCT), 169     new BigInteger([21], 1, CONSTRUCT), 170     new BigInteger([22], 1, CONSTRUCT), 171     new BigInteger([23], 1, CONSTRUCT), 172     new BigInteger([24], 1, CONSTRUCT), 173     new BigInteger([25], 1, CONSTRUCT), 174     new BigInteger([26], 1, CONSTRUCT), 175     new BigInteger([27], 1, CONSTRUCT), 176     new BigInteger([28], 1, CONSTRUCT), 177     new BigInteger([29], 1, CONSTRUCT), 178     new BigInteger([30], 1, CONSTRUCT), 179     new BigInteger([31], 1, CONSTRUCT), 180     new BigInteger([32], 1, CONSTRUCT), 181     new BigInteger([33], 1, CONSTRUCT), 182     new BigInteger([34], 1, CONSTRUCT), 183     new BigInteger([35], 1, CONSTRUCT), 184     new BigInteger([36], 1, CONSTRUCT) 185 ]; 186  187 // Used for parsing/radix conversion 188 BigInteger.digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""); 189  190 /* 191     Method: toString 192     Convert a <BigInteger> to a string. 193  194     When *base* is greater than 10, letters are upper case. 195  196     Parameters: 197  198         base - Optional base to represent the number in (default is base 10). 199                Must be between 2 and 36 inclusive, or an Error will be thrown. 200  201     Returns: 202  203         The string representation of the <BigInteger>. 204 */ 205 BigInteger.prototype.toString = function(base) { 206     base = +base || 10; 207     if (base < 2 || base > 36) { 208         throw new Error("illegal radix " + base + "."); 209     } 210     if (this._s === 0) { 211         return "0"; 212     } 213     if (base === 10) { 214         var str = this._s < 0 ? "-" : ""; 215         str += this._d[this._d.length - 1].toString(); 216         for (var i = this._d.length - 2; i >= 0; i--) { 217             var group = this._d[i].toString(); 218             while (group.length < BigInteger_base_log10) group = 0 + group; 219             str += group; 220         } 221         return str; 222     } 223     else { 224         var numerals = BigInteger.digits; 225         base = BigInteger.small[base]; 226         var sign = this._s; 227  228         var n = this.abs(); 229         var digits = []; 230         var digit; 231  232         while (n._s !== 0) { 233             var divmod = n.divRem(base); 234             n = divmod[0]; 235             digit = divmod[1]; 236             // TODO: This could be changed to unshift instead of reversing at the end. 237             // Benchmark both to compare speeds. 238             digits.push(numerals[digit.valueOf()]); 239         } 240         return (sign < 0 ? "-" : "") + digits.reverse().join(""); 241     } 242 }; 243  244 // Verify strings for parsing 245 BigInteger.radixRegex = [ 246     /^$/, 247     /^$/, 248     /^[01]*$/, 249     /^[012]*$/, 250     /^[0-3]*$/, 251     /^[0-4]*$/, 252     /^[0-5]*$/, 253     /^[0-6]*$/, 254     /^[0-7]*$/, 255     /^[0-8]*$/, 256     /^[0-9]*$/, 257     /^[0-9aA]*$/, 258     /^[0-9abAB]*$/, 259     /^[0-9abcABC]*$/, 260     /^[0-9a-dA-D]*$/, 261     /^[0-9a-eA-E]*$/, 262     /^[0-9a-fA-F]*$/, 263     /^[0-9a-gA-G]*$/, 264     /^[0-9a-hA-H]*$/, 265     /^[0-9a-iA-I]*$/, 266     /^[0-9a-jA-J]*$/, 267     /^[0-9a-kA-K]*$/, 268     /^[0-9a-lA-L]*$/, 269     /^[0-9a-mA-M]*$/, 270     /^[0-9a-nA-N]*$/, 271     /^[0-9a-oA-O]*$/, 272     /^[0-9a-pA-P]*$/, 273     /^[0-9a-qA-Q]*$/, 274     /^[0-9a-rA-R]*$/, 275     /^[0-9a-sA-S]*$/, 276     /^[0-9a-tA-T]*$/, 277     /^[0-9a-uA-U]*$/, 278     /^[0-9a-vA-V]*$/, 279     /^[0-9a-wA-W]*$/, 280     /^[0-9a-xA-X]*$/, 281     /^[0-9a-yA-Y]*$/, 282     /^[0-9a-zA-Z]*$/ 283 ]; 284  285 /* 286     Function: parse 287     Parse a string into a <BigInteger>. 288  289     *base* is optional but, if provided, must be from 2 to 36 inclusive. If 290     *base* is not provided, it will be guessed based on the leading characters 291     of *s* as follows: 292  293     - "0x" or "0X": *base* = 16 294     - "0c" or "0C": *base* = 8 295     - "0b" or "0B": *base* = 2 296     - else: *base* = 10 297  298     If no base is provided, or *base* is 10, the number can be in exponential 299     form. For example, these are all valid: 300  301     > BigInteger.parse("1e9");              // Same as "1000000000" 302     > BigInteger.parse("1.234*10^3");       // Same as 1234 303     > BigInteger.parse("56789 * 10 ** -2"); // Same as 567 304  305     If any characters fall outside the range defined by the radix, an exception 306     will be thrown. 307  308     Parameters: 309  310         s - The string to parse. 311         base - Optional radix (default is to guess based on *s*). 312  313     Returns: 314  315         a <BigInteger> instance. 316 */ 317 BigInteger.parse = function(s, base) { 318     // Expands a number in exponential form to decimal form. 319     // expandExponential("-13.441*10^5") === "1344100"; 320     // expandExponential("1.12300e-1") === "0.112300"; 321     // expandExponential(1000000000000000000000000000000) === "1000000000000000000000000000000"; 322     function expandExponential(str) { 323         str = str.replace(/\s*[*xX]\s*10\s*(\^|\*\*)\s*/, "e"); 324  325         return str.replace(/^([+\-])?(\d+)\.?(\d*)[eE]([+\-]?\d+)$/, function(x, s, n, f, c) { 326             c = +c; 327             var l = c < 0; 328             var i = n.length + c; 329             x = (l ? n : f).length; 330             c = ((c = Math.abs(c)) >= x ? c - x + l : 0); 331             var z = (new Array(c + 1)).join("0"); 332             var r = n + f; 333             return (s || "") + (l ? r = z + r : r += z).substr(0, i += l ? z.length : 0) + (i < r.length ? "." + r.substr(i) : ""); 334         }); 335     } 336  337     s = s.toString(); 338     if (typeof base === "undefined" || +base === 10) { 339         s = expandExponential(s); 340     } 341  342     var prefixRE; 343     if (typeof base === "undefined") { 344         prefixRE = 0[xcb]; 345     } 346     else if (base == 16) { 347         prefixRE = 0x; 348     } 349     else if (base == 8) { 350         prefixRE = 0c; 351     } 352     else if (base == 2) { 353         prefixRE = 0b; 354     } 355     else { 356         prefixRE = ‘‘; 357     } 358     var parts = new RegExp(^([+\\-]?)( + prefixRE + )?([0-9a-z]*)(?:\\.\\d*)?$, i).exec(s); 359     if (parts) { 360         var sign = parts[1] || "+"; 361         var baseSection = parts[2] || ""; 362         var digits = parts[3] || ""; 363  364         if (typeof base === "undefined") { 365             // Guess base 366             if (baseSection === "0x" || baseSection === "0X") { // Hex 367                 base = 16; 368             } 369             else if (baseSection === "0c" || baseSection === "0C") { // Octal 370                 base = 8; 371             } 372             else if (baseSection === "0b" || baseSection === "0B") { // Binary 373                 base = 2; 374             } 375             else { 376                 base = 10; 377             } 378         } 379         else if (base < 2 || base > 36) { 380             throw new Error("Illegal radix " + base + "."); 381         } 382  383         base = +base; 384  385         // Check for digits outside the range 386         if (!(BigInteger.radixRegex[base].test(digits))) { 387             throw new Error("Bad digit for radix " + base); 388         } 389  390         // Strip leading zeros, and convert to array 391         digits = digits.replace(/^0+/, "").split(""); 392         if (digits.length === 0) { 393             return ZERO; 394         } 395  396         // Get the sign (we know it‘s not zero) 397         sign = (sign === "-") ? -1 : 1; 398  399         // Optimize 10 400         if (base == 10) { 401             var d = []; 402             while (digits.length >= BigInteger_base_log10) { 403                 d.push(parseInt(digits.splice(digits.length-BigInteger.base_log10, BigInteger.base_log10).join(‘‘), 10)); 404             } 405             d.push(parseInt(digits.join(‘‘), 10)); 406             return new BigInteger(d, sign, CONSTRUCT); 407         } 408  409         // Do the conversion 410         var d = ZERO; 411         base = BigInteger.small[base]; 412         var small = BigInteger.small; 413         for (var i = 0; i < digits.length; i++) { 414             d = d.multiply(base).add(small[parseInt(digits[i], 36)]); 415         } 416         return new BigInteger(d._d, sign, CONSTRUCT); 417     } 418     else { 419         throw new Error("Invalid BigInteger format: " + s); 420     } 421 }; 422  423 /* 424     Function: add 425     Add two <BigIntegers>. 426  427     Parameters: 428  429         n - The number to add to *this*. Will be converted to a <BigInteger>. 430  431     Returns: 432  433         The numbers added together. 434  435     See Also: 436  437         <subtract>, <multiply>, <quotient>, <next> 438 */ 439 BigInteger.prototype.add = function(n) { 440     if (this._s === 0) { 441         return BigInteger(n); 442     } 443  444     n = BigInteger(n); 445     if (n._s === 0) { 446         return this; 447     } 448     if (this._s !== n._s) { 449         n = n.negate(); 450         return this.subtract(n); 451     } 452  453     var a = this._d; 454     var b = n._d; 455     var al = a.length; 456     var bl = b.length; 457     var sum = new Array(Math.max(al, bl) + 1); 458     var size = Math.min(al, bl); 459     var carry = 0; 460     var digit; 461  462     for (var i = 0; i < size; i++) { 463         digit = a[i] + b[i] + carry; 464         sum[i] = digit % BigInteger_base; 465         carry = (digit / BigInteger_base) | 0; 466     } 467     if (bl > al) { 468         a = b; 469         al = bl; 470     } 471     for (i = size; carry && i < al; i++) { 472         digit = a[i] + carry; 473         sum[i] = digit % BigInteger_base; 474         carry = (digit / BigInteger_base) | 0; 475     } 476     if (carry) { 477         sum[i] = carry; 478     } 479  480     for ( ; i < al; i++) { 481         sum[i] = a[i]; 482     } 483  484     return new BigInteger(sum, this._s, CONSTRUCT); 485 }; 486  487 /* 488     Function: negate 489     Get the additive inverse of a <BigInteger>. 490  491     Returns: 492  493         A <BigInteger> with the same magnatude, but with the opposite sign. 494  495     See Also: 496  497         <abs> 498 */ 499 BigInteger.prototype.negate = function() { 500     return new BigInteger(this._d, (-this._s) | 0, CONSTRUCT); 501 }; 502  503 /* 504     Function: abs 505     Get the absolute value of a <BigInteger>. 506  507     Returns: 508  509         A <BigInteger> with the same magnatude, but always positive (or zero). 510  511     See Also: 512  513         <negate> 514 */ 515 BigInteger.prototype.abs = function() { 516     return (this._s < 0) ? this.negate() : this; 517 }; 518  519 /* 520     Function: subtract 521     Subtract two <BigIntegers>. 522  523     Parameters: 524  525         n - The number to subtract from *this*. Will be converted to a <BigInteger>. 526  527     Returns: 528  529         The *n* subtracted from *this*. 530  531     See Also: 532  533         <add>, <multiply>, <quotient>, <prev> 534 */ 535 BigInteger.prototype.subtract = function(n) { 536     if (this._s === 0) { 537         return BigInteger(n).negate(); 538     } 539  540     n = BigInteger(n); 541     if (n._s === 0) { 542         return this; 543     } 544     if (this._s !== n._s) { 545         n = n.negate(); 546         return this.add(n); 547     } 548  549     var m = this; 550     // negative - negative => -|a| - -|b| => -|a| + |b| => |b| - |a| 551     if (this._s < 0) { 552         m = new BigInteger(n._d, 1, CONSTRUCT); 553         n = new BigInteger(this._d, 1, CONSTRUCT); 554     } 555  556     // Both are positive => a - b 557     var sign = m.compareAbs(n); 558     if (sign === 0) { 559         return ZERO; 560     } 561     else if (sign < 0) { 562         // swap m and n 563         var t = n; 564         n = m; 565         m = t; 566     } 567  568     // a > b 569     var a = m._d; 570     var b = n._d; 571     var al = a.length; 572     var bl = b.length; 573     var diff = new Array(al); // al >= bl since a > b 574     var borrow = 0; 575     var i; 576     var digit; 577  578     for (i = 0; i < bl; i++) { 579         digit = a[i] - borrow - b[i]; 580         if (digit < 0) { 581             digit += BigInteger_base; 582             borrow = 1; 583         } 584         else { 585             borrow = 0; 586         } 587         diff[i] = digit; 588     } 589     for (i = bl; i < al; i++) { 590         digit = a[i] - borrow; 591         if (digit < 0) { 592             digit += BigInteger_base; 593         } 594         else { 595             diff[i++] = digit; 596             break; 597         } 598         diff[i] = digit; 599     } 600     for ( ; i < al; i++) { 601         diff[i] = a[i]; 602     } 603  604     return new BigInteger(diff, sign, CONSTRUCT); 605 }; 606  607 (function() { 608     function addOne(n, sign) { 609         var a = n._d; 610         var sum = a.slice(); 611         var carry = true; 612         var i = 0; 613  614         while (true) { 615             var digit = (a[i] || 0) + 1; 616             sum[i] = digit % BigInteger_base; 617             if (digit <= BigInteger_base - 1) { 618                 break; 619             } 620             ++i; 621         } 622  623         return new BigInteger(sum, sign, CONSTRUCT); 624     } 625  626     function subtractOne(n, sign) { 627         var a = n._d; 628         var sum = a.slice(); 629         var borrow = true; 630         var i = 0; 631  632         while (true) { 633             var digit = (a[i] || 0) - 1; 634             if (digit < 0) { 635                 sum[i] = digit + BigInteger_base; 636             } 637             else { 638                 sum[i] = digit; 639                 break; 640             } 641             ++i; 642         } 643  644         return new BigInteger(sum, sign, CONSTRUCT); 645     } 646  647     /* 648         Function: next 649         Get the next <BigInteger> (add one). 650  651         Returns: 652  653             *this* + 1. 654  655         See Also: 656  657             <add>, <prev> 658     */ 659     BigInteger.prototype.next = function() { 660         switch (this._s) { 661         case 0: 662             return ONE; 663         case -1: 664             return subtractOne(this, -1); 665         // case 1: 666         default: 667             return addOne(this, 1); 668         } 669     }; 670  671     /* 672         Function: prev 673         Get the previous <BigInteger> (subtract one). 674  675         Returns: 676  677             *this* - 1. 678  679         See Also: 680  681             <next>, <subtract> 682     */ 683     BigInteger.prototype.prev = function() { 684         switch (this._s) { 685         case 0: 686             return M_ONE; 687         case -1: 688             return addOne(this, -1); 689         // case 1: 690         default: 691             return subtractOne(this, 1); 692         } 693     }; 694 })(); 695  696 /* 697     Function: compareAbs 698     Compare the absolute value of two <BigIntegers>. 699  700     Calling <compareAbs> is faster than calling <abs> twice, then <compare>. 701  702     Parameters: 703  704         n - The number to compare to *this*. Will be converted to a <BigInteger>. 705  706     Returns: 707  708         -1, 0, or +1 if *|this|* is less than, equal to, or greater than *|n|*. 709  710     See Also: 711  712         <compare>, <abs> 713 */ 714 BigInteger.prototype.compareAbs = function(n) { 715     if (this === n) { 716         return 0; 717     } 718  719     if (!(n instanceof BigInteger)) { 720         if (!isFinite(n)) { 721             return(isNaN(n) ? n : -1); 722         } 723         n = BigInteger(n); 724     } 725  726     if (this._s === 0) { 727         return (n._s !== 0) ? -1 : 0; 728     } 729     if (n._s === 0) { 730         return 1; 731     } 732  733     var l = this._d.length; 734     var nl = n._d.length; 735     if (l < nl) { 736         return -1; 737     } 738     else if (l > nl) { 739         return 1; 740     } 741  742     var a = this._d; 743     var b = n._d; 744     for (var i = l-1; i >= 0; i--) { 745         if (a[i] !== b[i]) { 746             return a[i] < b[i] ? -1 : 1; 747         } 748     } 749  750     return 0; 751 }; 752  753 /* 754     Function: compare 755     Compare two <BigIntegers>. 756  757     Parameters: 758  759         n - The number to compare to *this*. Will be converted to a <BigInteger>. 760  761     Returns: 762  763         -1, 0, or +1 if *this* is less than, equal to, or greater than *n*. 764  765     See Also: 766  767         <compareAbs>, <isPositive>, <isNegative>, <isUnit> 768 */ 769 BigInteger.prototype.compare = function(n) { 770     if (this === n) { 771         return 0; 772     } 773  774     n = BigInteger(n); 775  776     if (this._s === 0) { 777         return -n._s; 778     } 779  780     if (this._s === n._s) { // both positive or both negative 781         var cmp = this.compareAbs(n); 782         return cmp * this._s; 783     } 784     else { 785         return this._s; 786     } 787 }; 788  789 /* 790     Function: isUnit 791     Return true iff *this* is either 1 or -1. 792  793     Returns: 794  795         true if *this* compares equal to <BigInteger.ONE> or <BigInteger.M_ONE>. 796  797     See Also: 798  799         <isZero>, <isNegative>, <isPositive>, <compareAbs>, <compare>, 800         <BigInteger.ONE>, <BigInteger.M_ONE> 801 */ 802 BigInteger.prototype.isUnit = function() { 803     return this === ONE || 804         this === M_ONE || 805         (this._d.length === 1 && this._d[0] === 1); 806 }; 807  808 /* 809     Function: multiply 810     Multiply two <BigIntegers>. 811  812     Parameters: 813  814         n - The number to multiply *this* by. Will be converted to a 815         <BigInteger>. 816  817     Returns: 818  819         The numbers multiplied together. 820  821     See Also: 822  823         <add>, <subtract>, <quotient>, <square> 824 */ 825 BigInteger.prototype.multiply = function(n) { 826     // TODO: Consider adding Karatsuba multiplication for large numbers 827     if (this._s === 0) { 828         return ZERO; 829     } 830  831     n = BigInteger(n); 832     if (n._s === 0) { 833         return ZERO; 834     } 835     if (this.isUnit()) { 836         if (this._s < 0) { 837             return n.negate(); 838         } 839         return n; 840     } 841     if (n.isUnit()) { 842         if (n._s < 0) { 843             return this.negate(); 844         } 845         return this; 846     } 847     if (this === n) { 848         return this.square(); 849     } 850  851     var r = (this._d.length >= n._d.length); 852     var a = (r ? this : n)._d; // a will be longer than b 853     var b = (r ? n : this)._d; 854     var al = a.length; 855     var bl = b.length; 856  857     var pl = al + bl; 858     var partial = new Array(pl); 859     var i; 860     for (i = 0; i < pl; i++) { 861         partial[i] = 0; 862     } 863  864     for (i = 0; i < bl; i++) { 865         var carry = 0; 866         var bi = b[i]; 867         var jlimit = al + i; 868         var digit; 869         for (var j = i; j < jlimit; j++) { 870             digit = partial[j] + bi * a[j - i] + carry; 871             carry = (digit / BigInteger_base) | 0; 872             partial[j] = (digit % BigInteger_base) | 0; 873         } 874         if (carry) { 875             digit = partial[j] + carry; 876             carry = (digit / BigInteger_base) | 0; 877             partial[j] = digit % BigInteger_base; 878         } 879     } 880     return new BigInteger(partial, this._s * n._s, CONSTRUCT); 881 }; 882  883 // Multiply a BigInteger by a single-digit native number 884 // Assumes that this and n are >= 0 885 // This is not really intended to be used outside the library itself 886 BigInteger.prototype.multiplySingleDigit = function(n) { 887     if (n === 0 || this._s === 0) { 888         return ZERO; 889     } 890     if (n === 1) { 891         return this; 892     } 893  894     var digit; 895     if (this._d.length === 1) { 896         digit = this._d[0] * n; 897         if (digit >= BigInteger_base) { 898             return new BigInteger([(digit % BigInteger_base)|0, 899                     (digit / BigInteger_base)|0], 1, CONSTRUCT); 900         } 901         return new BigInteger([digit], 1, CONSTRUCT); 902     } 903  904     if (n === 2) { 905         return this.add(this); 906     } 907     if (this.isUnit()) { 908         return new BigInteger([n], 1, CONSTRUCT); 909     } 910  911     var a = this._d; 912     var al = a.length; 913  914     var pl = al + 1; 915     var partial = new Array(pl); 916     for (var i = 0; i < pl; i++) { 917         partial[i] = 0; 918     } 919  920     var carry = 0; 921     for (var j = 0; j < al; j++) { 922         digit = n * a[j] + carry; 923         carry = (digit / BigInteger_base) | 0; 924         partial[j] = (digit % BigInteger_base) | 0; 925     } 926     if (carry) { 927         partial[j] = carry; 928     } 929  930     return new BigInteger(partial, 1, CONSTRUCT); 931 }; 932  933 /* 934     Function: square 935     Multiply a <BigInteger> by itself. 936  937     This is slightly faster than regular multiplication, since it removes the 938     duplicated multiplcations. 939  940     Returns: 941  942         > this.multiply(this) 943  944     See Also: 945         <multiply> 946 */ 947 BigInteger.prototype.square = function() { 948     // Normally, squaring a 10-digit number would take 100 multiplications. 949     // Of these 10 are unique diagonals, of the remaining 90 (100-10), 45 are repeated. 950     // This procedure saves (N*(N-1))/2 multiplications, (e.g., 45 of 100 multiplies). 951     // Based on code by Gary Darby, Intellitech Systems Inc., www.DelphiForFun.org 952  953     if (this._s === 0) { 954         return ZERO; 955     } 956     if (this.isUnit()) { 957         return ONE; 958     } 959  960     var digits = this._d; 961     var length = digits.length; 962     var imult1 = new Array(length + length + 1); 963     var product, carry, k; 964     var i; 965  966     // Calculate diagonal 967     for (i = 0; i < length; i++) { 968         k = i * 2; 969         product = digits[i] * digits[i]; 970         carry = (product / BigInteger_base) | 0; 971         imult1[k] = product % BigInteger_base; 972         imult1[k + 1] = carry; 973     } 974  975     // Calculate repeating part 976     for (i = 0; i < length; i++) { 977         carry = 0; 978         k = i * 2 + 1; 979         for (var j = i + 1; j < length; j++, k++) { 980             product = digits[j] * digits[i] * 2 + imult1[k] + carry; 981             carry = (product / BigInteger_base) | 0; 982             imult1[k] = product % BigInteger_base; 983         } 984         k = length + i; 985         var digit = carry + imult1[k]; 986         carry = (digit / BigInteger_base) | 0; 987         imult1[k] = digit % BigInteger_base; 988         imult1[k + 1] += carry; 989     } 990  991     return new BigInteger(imult1, 1, CONSTRUCT); 992 }; 993  994 /* 995     Function: quotient 996     Divide two <BigIntegers> and truncate towards zero. 997  998     <quotient> throws an exception if *n* is zero. 999 1000     Parameters:1001 1002         n - The number to divide *this* by. Will be converted to a <BigInteger>.1003 1004     Returns:1005 1006         The *this* / *n*, truncated to an integer.1007 1008     See Also:1009 1010         <add>, <subtract>, <multiply>, <divRem>, <remainder>1011 */1012 BigInteger.prototype.quotient = function(n) {1013     return this.divRem(n)[0];1014 };1015 1016 /*1017     Function: divide1018     Deprecated synonym for <quotient>.1019 */1020 BigInteger.prototype.divide = BigInteger.prototype.quotient;1021 1022 /*1023     Function: remainder1024     Calculate the remainder of two <BigIntegers>.1025 1026     <remainder> throws an exception if *n* is zero.1027 1028     Parameters:1029 1030         n - The remainder after *this* is divided *this* by *n*. Will be1031             converted to a <BigInteger>.1032 1033     Returns:1034 1035         *this* % *n*.1036 1037     See Also:1038 1039         <divRem>, <quotient>1040 */1041 BigInteger.prototype.remainder = function(n) {1042     return this.divRem(n)[1];1043 };1044 1045 /*1046     Function: divRem1047     Calculate the integer quotient and remainder of two <BigIntegers>.1048 1049     <divRem> throws an exception if *n* is zero.1050 1051     Parameters:1052 1053         n - The number to divide *this* by. Will be converted to a <BigInteger>.1054 1055     Returns:1056 1057         A two-element array containing the quotient and the remainder.1058 1059         > a.divRem(b)1060 1061         is exactly equivalent to1062 1063         > [a.quotient(b), a.remainder(b)]1064 1065         except it is faster, because they are calculated at the same time.1066 1067     See Also:1068 1069         <quotient>, <remainder>1070 */1071 BigInteger.prototype.divRem = function(n) {1072     n = BigInteger(n);1073     if (n._s === 0) {1074         throw new Error("Divide by zero");1075     }1076     if (this._s === 0) {1077         return [ZERO, ZERO];1078     }1079     if (n._d.length === 1) {1080         return this.divRemSmall(n._s * n._d[0]);1081     }1082 1083     // Test for easy cases -- |n1| <= |n2|1084     switch (this.compareAbs(n)) {1085     case 0: // n1 == n21086         return [this._s === n._s ? ONE : M_ONE, ZERO];1087     case -1: // |n1| < |n2|1088         return [ZERO, this];1089     }1090 1091     var sign = this._s * n._s;1092     var a = n.abs();1093     var b_digits = this._d;1094     var b_index = b_digits.length;1095     var digits = n._d.length;1096     var quot = [];1097     var guess;1098 1099     var part = new BigInteger([], 0, CONSTRUCT);1100     part._s = 1;1101 1102     while (b_index) {1103         part._d.unshift(b_digits[--b_index]);1104 1105         if (part.compareAbs(n) < 0) {1106             quot.push(0);1107             continue;1108         }1109         if (part._s === 0) {1110             guess = 0;1111         }1112         else {1113             var xlen = part._d.length, ylen = a._d.length;1114             var highx = part._d[xlen-1]*BigInteger_base + part._d[xlen-2];1115             var highy = a._d[ylen-1]*BigInteger_base + a._d[ylen-2];1116             if (part._d.length > a._d.length) {1117                 // The length of part._d can either match a._d length,1118                 // or exceed it by one.1119                 highx = (highx+1)*BigInteger_base;1120             }1121             guess = Math.ceil(highx/highy);1122         }1123         do {1124             var check = a.multiplySingleDigit(guess);1125             if (check.compareAbs(part) <= 0) {1126                 break;1127             }1128             guess--;1129         } while (guess);1130 1131         quot.push(guess);1132         if (!guess) {1133             continue;1134         }1135         var diff = part.subtract(check);1136         part._d = diff._d.slice();1137         if (part._d.length === 0) {1138             part._s = 0;1139         }1140     }1141 1142     return [new BigInteger(quot.reverse(), sign, CONSTRUCT),1143            new BigInteger(part._d, this._s, CONSTRUCT)];1144 };1145 1146 // Throws an exception if n is outside of (-BigInteger.base, -1] or1147 // [1, BigInteger.base).  It‘s not necessary to call this, since the1148 // other division functions will call it if they are able to.1149 BigInteger.prototype.divRemSmall = function(n) {1150     var r;1151     n = +n;1152     if (n === 0) {1153         throw new Error("Divide by zero");1154     }1155 1156     var n_s = n < 0 ? -1 : 1;1157     var sign = this._s * n_s;1158     n = Math.abs(n);1159 1160     if (n < 1 || n >= BigInteger_base) {1161         throw new Error("Argument out of range");1162     }1163 1164     if (this._s === 0) {1165         return [ZERO, ZERO];1166     }1167 1168     if (n === 1 || n === -1) {1169         return [(sign === 1) ? this.abs() : new BigInteger(this._d, sign, CONSTRUCT), ZERO];1170     }1171 1172     // 2 <= n < BigInteger_base1173 1174     // divide a single digit by a single digit1175     if (this._d.length === 1) {1176         var q = new BigInteger([(this._d[0] / n) | 0], 1, CONSTRUCT);1177         r = new BigInteger([(this._d[0] % n) | 0], 1, CONSTRUCT);1178         if (sign < 0) {1179             q = q.negate();1180         }1181         if (this._s < 0) {1182             r = r.negate();1183         }1184         return [q, r];1185     }1186 1187     var digits = this._d.slice();1188     var quot = new Array(digits.length);1189     var part = 0;1190     var diff = 0;1191     var i = 0;1192     var guess;1193 1194     while (digits.length) {1195         part = part * BigInteger_base + digits[digits.length - 1];1196         if (part < n) {1197             quot[i++] = 0;1198             digits.pop();1199             diff = BigInteger_base * diff + part;1200             continue;1201         }1202         if (part === 0) {1203             guess = 0;1204         }1205         else {1206             guess = (part / n) | 0;1207         }1208 1209         var check = n * guess;1210         diff = part - check;1211         quot[i++] = guess;1212         if (!guess) {1213             digits.pop();1214             continue;1215         }1216 1217         digits.pop();1218         part = diff;1219     }1220 1221     r = new BigInteger([diff], 1, CONSTRUCT);1222     if (this._s < 0) {1223         r = r.negate();1224     }1225     return [new BigInteger(quot.reverse(), sign, CONSTRUCT), r];1226 };1227 1228 /*1229     Function: isEven1230     Return true iff *this* is divisible by two.1231 1232     Note that <BigInteger.ZERO> is even.1233 1234     Returns:1235 1236         true if *this* is even, false otherwise.1237 1238     See Also:1239 1240         <isOdd>1241 */1242 BigInteger.prototype.isEven = function() {1243     var digits = this._d;1244     return this._s === 0 || digits.length === 0 || (digits[0] % 2) === 0;1245 };1246 1247 /*1248     Function: isOdd1249     Return true iff *this* is not divisible by two.1250 1251     Returns:1252 1253         true if *this* is odd, false otherwise.1254 1255     See Also:1256 1257         <isEven>1258 */1259 BigInteger.prototype.isOdd = function() {1260     return !this.isEven();1261 };1262 1263 /*1264     Function: sign1265     Get the sign of a <BigInteger>.1266 1267     Returns:1268 1269         * -1 if *this* < 01270         * 0 if *this* == 01271         * +1 if *this* > 01272 1273     See Also:1274 1275         <isZero>, <isPositive>, <isNegative>, <compare>, <BigInteger.ZERO>1276 */1277 BigInteger.prototype.sign = function() {1278     return this._s;1279 };1280 1281 /*1282     Function: isPositive1283     Return true iff *this* > 0.1284 1285     Returns:1286 1287         true if *this*.compare(<BigInteger.ZERO>) == 1.1288 1289     See Also:1290 1291         <sign>, <isZero>, <isNegative>, <isUnit>, <compare>, <BigInteger.ZERO>1292 */1293 BigInteger.prototype.isPositive = function() {1294     return this._s > 0;1295 };1296 1297 /*1298     Function: isNegative1299     Return true iff *this* < 0.1300 1301     Returns:1302 1303         true if *this*.compare(<BigInteger.ZERO>) == -1.1304 1305     See Also:1306 1307         <sign>, <isPositive>, <isZero>, <isUnit>, <compare>, <BigInteger.ZERO>1308 */1309 BigInteger.prototype.isNegative = function() {1310     return this._s < 0;1311 };1312 1313 /*1314     Function: isZero1315     Return true iff *this* == 0.1316 1317     Returns:1318 1319         true if *this*.compare(<BigInteger.ZERO>) == 0.1320 1321     See Also:1322 1323         <sign>, <isPositive>, <isNegative>, <isUnit>, <BigInteger.ZERO>1324 */1325 BigInteger.prototype.isZero = function() {1326     return this._s === 0;1327 };1328 1329 /*1330     Function: exp101331     Multiply a <BigInteger> by a power of 10.1332 1333     This is equivalent to, but faster than1334 1335     > if (n >= 0) {1336     >     return this.multiply(BigInteger("1e" + n));1337     > }1338     > else { // n <= 01339     >     return this.quotient(BigInteger("1e" + -n));1340     > }1341 1342     Parameters:1343 1344         n - The power of 10 to multiply *this* by. *n* is converted to a1345         javascipt number and must be no greater than <BigInteger.MAX_EXP>1346         (0x7FFFFFFF), or an exception will be thrown.1347 1348     Returns:1349 1350         *this* * (10 ** *n*), truncated to an integer if necessary.1351 1352     See Also:1353 1354         <pow>, <multiply>1355 */1356 BigInteger.prototype.exp10 = function(n) {1357     n = +n;1358     if (n === 0) {1359         return this;1360     }1361     if (Math.abs(n) > Number(MAX_EXP)) {1362         throw new Error("exponent too large in BigInteger.exp10");1363     }1364     if (n > 0) {1365         var k = new BigInteger(this._d.slice(), this._s, CONSTRUCT);1366 1367         for (; n >= BigInteger_base_log10; n -= BigInteger_base_log10) {1368             k._d.unshift(0);1369         }1370         if (n == 0)1371             return k;1372         k._s = 1;1373         k = k.multiplySingleDigit(Math.pow(10, n));1374         return (this._s < 0 ? k.negate() : k);1375     } else if (-n >= this._d.length*BigInteger_base_log10) {1376         return ZERO;1377     } else {1378         var k = new BigInteger(this._d.slice(), this._s, CONSTRUCT);1379 1380         for (n = -n; n >= BigInteger_base_log10; n -= BigInteger_base_log10) {1381             k._d.shift();1382         }1383         return (n == 0) ? k : k.divRemSmall(Math.pow(10, n))[0];1384     }1385 };1386 1387 /*1388     Function: pow1389     Raise a <BigInteger> to a power.1390 1391     In this implementation, 0**0 is 1.1392 1393     Parameters:1394 1395         n - The exponent to raise *this* by. *n* must be no greater than1396         <BigInteger.MAX_EXP> (0x7FFFFFFF), or an exception will be thrown.1397 1398     Returns:1399 1400         *this* raised to the *nth* power.1401 1402     See Also:1403 1404         <modPow>1405 */1406 BigInteger.prototype.pow = function(n) {1407     if (this.isUnit()) {1408         if (this._s > 0) {1409             return this;1410         }1411         else {1412             return BigInteger(n).isOdd() ? this : this.negate();1413         }1414     }1415 1416     n = BigInteger(n);1417     if (n._s === 0) {1418         return ONE;1419     }1420     else if (n._s < 0) {1421         if (this._s === 0) {1422             throw new Error("Divide by zero");1423         }1424         else {1425             return ZERO;1426         }1427     }1428     if (this._s === 0) {1429         return ZERO;1430     }1431     if (n.isUnit()) {1432         return this;1433     }1434 1435     if (n.compareAbs(MAX_EXP) > 0) {1436         throw new Error("exponent too large in BigInteger.pow");1437     }1438     var x = this;1439     var aux = ONE;1440     var two = BigInteger.small[2];1441 1442     while (n.isPositive()) {1443         if (n.isOdd()) {1444             aux = aux.multiply(x);1445             if (n.isUnit()) {1446                 return aux;1447             }1448         }1449         x = x.square();1450         n = n.quotient(two);1451     }1452 1453     return aux;1454 };1455 1456 /*1457     Function: modPow1458     Raise a <BigInteger> to a power (mod m).1459 1460     Because it is reduced by a modulus, <modPow> is not limited by1461     <BigInteger.MAX_EXP> like <pow>.1462 1463     Parameters:1464 1465         exponent - The exponent to raise *this* by. Must be positive.1466         modulus - The modulus.1467 1468     Returns:1469 1470         *this* ^ *exponent* (mod *modulus*).1471 1472     See Also:1473 1474         <pow>, <mod>1475 */1476 BigInteger.prototype.modPow = function(exponent, modulus) {1477     var result = ONE;1478     var base = this;1479 1480     while (exponent.isPositive()) {1481         if (exponent.isOdd()) {1482             result = result.multiply(base).remainder(modulus);1483         }1484 1485         exponent = exponent.quotient(BigInteger.small[2]);1486         if (exponent.isPositive()) {1487             base = base.square().remainder(modulus);1488         }1489     }1490 1491     return result;1492 };1493 1494 /*1495     Function: log1496     Get the natural logarithm of a <BigInteger> as a native JavaScript number.1497 1498     This is equivalent to1499 1500     > Math.log(this.toJSValue())1501 1502     but handles values outside of the native number range.1503 1504     Returns:1505 1506         log( *this* )1507 1508     See Also:1509 1510         <toJSValue>1511 */1512 BigInteger.prototype.log = function() {1513     switch (this._s) {1514     case 0:     return -Infinity;1515     case -1: return NaN;1516     default: // Fall through.1517     }1518 1519     var l = this._d.length;1520 1521     if (l*BigInteger_base_log10 < 30) {1522         return Math.log(this.valueOf());1523     }1524 1525     var N = Math.ceil(30/BigInteger_base_log10);1526     var firstNdigits = this._d.slice(l - N);1527     return Math.log((new BigInteger(firstNdigits, 1, CONSTRUCT)).valueOf()) + (l - N) * Math.log(BigInteger_base);1528 };1529 1530 /*1531     Function: valueOf1532     Convert a <BigInteger> to a native JavaScript integer.1533 1534     This is called automatically by JavaScipt to convert a <BigInteger> to a1535     native value.1536 1537     Returns:1538 1539         > parseInt(this.toString(), 10)1540 1541     See Also:1542 1543         <toString>, <toJSValue>1544 */1545 BigInteger.prototype.valueOf = function() {1546     return parseInt(this.toString(), 10);1547 };1548 1549 /*1550     Function: toJSValue1551     Convert a <BigInteger> to a native JavaScript integer.1552 1553     This is the same as valueOf, but more explicitly named.1554 1555     Returns:1556 1557         > parseInt(this.toString(), 10)1558 1559     See Also:1560 1561         <toString>, <valueOf>1562 */1563 BigInteger.prototype.toJSValue =http://www.mamicode.com/ function() {1564     return parseInt(this.toString(), 10);1565 };1566 1567 var MAX_EXP = BigInteger(0x7FFFFFFF);1568 // Constant: MAX_EXP1569 // The largest exponent allowed in <pow> and <exp10> (0x7FFFFFFF or 2147483647).1570 BigInteger.MAX_EXP = MAX_EXP;1571 1572 (function() {1573     function makeUnary(fn) {1574         return function(a) {1575             return fn.call(BigInteger(a));1576         };1577     }1578 1579     function makeBinary(fn) {1580         return function(a, b) {1581             return fn.call(BigInteger(a), BigInteger(b));1582         };1583     }1584 1585     function makeTrinary(fn) {1586         return function(a, b, c) {1587             return fn.call(BigInteger(a), BigInteger(b), BigInteger(c));1588         };1589     }1590 1591     (function() {1592         var i, fn;1593         var unary = "toJSValue,isEven,isOdd,sign,isZero,isNegative,abs,isUnit,square,negate,isPositive,toString,next,prev,log".split(",");1594         var binary = "compare,remainder,divRem,subtract,add,quotient,divide,multiply,pow,compareAbs".split(",");1595         var trinary = ["modPow"];1596 1597         for (i = 0; i < unary.length; i++) {1598             fn = unary[i];1599             BigInteger[fn] = makeUnary(BigInteger.prototype[fn]);1600         }1601 1602         for (i = 0; i < binary.length; i++) {1603             fn = binary[i];1604             BigInteger[fn] = makeBinary(BigInteger.prototype[fn]);1605         }1606 1607         for (i = 0; i < trinary.length; i++) {1608             fn = trinary[i];1609             BigInteger[fn] = makeTrinary(BigInteger.prototype[fn]);1610         }1611 1612         BigInteger.exp10 = function(x, n) {1613             return BigInteger(x).exp10(n);1614         };1615     })();1616 })();1617 1618 exports.BigInteger = BigInteger;1619 })(typeof exports !== undefined ? exports : this);