Merge lp:~rpadovani/ubuntu-calculator-app/1332567 into lp:~ubuntu-calculator-dev/ubuntu-calculator-app/old_trunk

Proposed by Riccardo Padovani
Status: Merged
Approved by: Alan Pope 🍺🐧🐱 πŸ¦„
Approved revision: 286
Merged at revision: 288
Proposed branch: lp:~rpadovani/ubuntu-calculator-app/1332567
Merge into: lp:~ubuntu-calculator-dev/ubuntu-calculator-app/old_trunk
Diff against target: 1246 lines (+189/-171)
1 file modified
bignumber.js (+189/-171)
To merge this branch: bzr merge lp:~rpadovani/ubuntu-calculator-app/1332567
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Renato Araujo Oliveira Filho (community) Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Bartosz Kosiorek Needs Information
Victor Thompson (community) Approve
Mihir Soni Approve
Alan Pope 🍺🐧🐱 πŸ¦„ Pending
Review via email: mp+225225@code.launchpad.net

Commit message

Updated bignumber.js, added a workaround for bug #1332567

Description of the change

Due bug #1332567 when device is connected to charger it does wrong divisions.
I'm pretty sure I have identified the origin of the bug: in bignumber.js there is function named "division", which has a do/while cycle inside.

Before the do/while cycle all vars are equal on desktop and on device, but after the cycle the array named qc is different.

So, I started to debug the do/while cycle, but everytime I add a console.log() in the do/while cycle, the bug disappears. I think is an Heisenbug[1].

I suppose the bug is in the QT 5.3 Javascript Interpreter, and I'm working to reproduce the bug with a simplier code.

Until the fix of the bug in the interpreter, I suggest to add a console.log() in the do/while cycle as a workaround.

Also, I updated the library to latest version

[1]https://en.wikipedia.org/wiki/Unusual_software_bug

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Bartosz Kosiorek (gang65) wrote :

Looks ok. Great job!

review: Approve
Revision history for this message
Mihir Soni (mihirsoni) wrote :

Change looks good to me , it works great on desktop with new upgraded version of js file.
But still haven't tested on device.

review: Approve
Revision history for this message
Bartosz Kosiorek (gang65) wrote :

Could you please submit bug report for QT 5.3 Javascript Interpreter?

review: Needs Information
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
285. By Riccardo Padovani

Merged lp:~vthompson/ubuntu-calculator-app/test-fix-1332567

286. By Riccardo Padovani

Removed old workaround

Revision history for this message
Riccardo Padovani (rpadovani) wrote :

I merged Victor fix that is better. Seems that in specific occasions the QT interpreter is too slow. I'll talk with someone in the sdk team and I'll report the bug upstream

Revision history for this message
Victor Thompson (vthompson) wrote :

lgtm!

review: Approve
Revision history for this message
Bartosz Kosiorek (gang65) wrote :

Great work.
One more comment.

Could you please extend autopilot test case, to handle this divine problem in future?

You could change for example from:
    def test_divide_positive(self):
        self.main_view.calculate_operation("4/2")
        self._assert_result("2")

To:
    def test_divide_positive(self):
        self.main_view.calculate_operation("4/5")
        self._assert_result("0.8")

Maybe it will be good to submit this bignumber fix to upstream:
https://github.com/MikeMcl/bignumber.js/

review: Needs Information
Revision history for this message
Bartosz Kosiorek (gang65) wrote :

Or maybe better 4.5/2 = 2.25

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Riccardo Padovani (rpadovani) wrote :

> Could you please extend autopilot test case, to handle this divine problem in future?

We have a testcase about this, is 1/3. It's thanks to this test case we found
the bug

> Maybe it will be good to submit this bignumber fix to upstream:
> https://github.com/MikeMcl/bignumber.js/

I reported the bug upstream and linked Victor's patch. I know it's trivial
change, but I prefer to know author's opinion before do a MR :-)

Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

works for me.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bignumber.js'
--- bignumber.js 2014-04-26 17:59:39 +0000
+++ bignumber.js 2014-07-02 14:22:11 +0000
@@ -1,12 +1,19 @@
1/* bignumber.js v1.3.0 https://github.com/MikeMcl/bignumber.js/LICENCE */1/*! bignumber.js v1.4.1 https://github.com/MikeMcl/bignumber.js/LICENCE */
22
3var BN;3var BN;
44
5/* Due bug https://bugs.launchpad.net/ubuntu-calculator-app/+bug/1332567
6 * there is a change after line 598, remember to add it when you update
7 * the file
8 * See
9 * https://code.launchpad.net/~vthompson/ubuntu-calculator-app/test-fix-1332567
10 */
11
5;(function ( global ) {12;(function ( global ) {
6 'use strict';13 'use strict';
714
8 /*15 /*
9 bignumber.js v1.3.016 bignumber.js v1.4.1
10 A JavaScript library for arbitrary-precision arithmetic.17 A JavaScript library for arbitrary-precision arithmetic.
11 https://github.com/MikeMcl/bignumber.js18 https://github.com/MikeMcl/bignumber.js
12 Copyright (c) 2012 Michael Mclaughlin <M8ch88l@gmail.com>19 Copyright (c) 2012 Michael Mclaughlin <M8ch88l@gmail.com>
@@ -114,7 +121,7 @@
114 x['s'] = n['s'];121 x['s'] = n['s'];
115 x['e'] = n['e'];122 x['e'] = n['e'];
116 x['c'] = ( n = n['c'] ) ? n.slice() : n;123 x['c'] = ( n = n['c'] ) ? n.slice() : n;
117 return124 return;
118 }125 }
119 }126 }
120127
@@ -122,7 +129,7 @@
122 if ( typeof n != 'string' ) {129 if ( typeof n != 'string' ) {
123 n = ( isNum = typeof n == 'number' ||130 n = ( isNum = typeof n == 'number' ||
124 Object.prototype.toString.call(n) == '[object Number]' ) &&131 Object.prototype.toString.call(n) == '[object Number]' ) &&
125 n === 0 && 1 / n < 0 ? '-0' : n + ''132 n === 0 && 1 / n < 0 ? '-0' : n + '';
126 }133 }
127134
128 orig = n;135 orig = n;
@@ -130,7 +137,7 @@
130 if ( b === e && isValid.test(n) ) {137 if ( b === e && isValid.test(n) ) {
131138
132 // Determine sign.139 // Determine sign.
133 x['s'] = n.charAt(0) == '-' ? ( n = n.slice(1), -1 ) : 1140 x['s'] = n.charAt(0) == '-' ? ( n = n.slice(1), -1 ) : 1;
134141
135 // Either n is not a valid BigNumber or a base has been specified.142 // Either n is not a valid BigNumber or a base has been specified.
136 } else {143 } else {
@@ -139,7 +146,7 @@
139 // Ensure return value is rounded to DECIMAL_PLACES as with other bases.146 // Ensure return value is rounded to DECIMAL_PLACES as with other bases.
140 if ( b == 10 ) {147 if ( b == 10 ) {
141148
142 return setMode( n, DECIMAL_PLACES, ROUNDING_MODE )149 return setMode( n, DECIMAL_PLACES, ROUNDING_MODE );
143 }150 }
144151
145 n = trim.call(n).replace( /^\+(?!-)/, '' );152 n = trim.call(n).replace( /^\+(?!-)/, '' );
@@ -163,22 +170,22 @@
163170
164 if ( isNum ) {171 if ( isNum ) {
165172
166 if ( n.replace( /^0\.0*|\./, '' ).length > 11 ) {173 if ( n.replace( /^0\.0*|\./, '' ).length > 15 ) {
167174
168 // 'new BigNumber() number type has more than 11 significant digits: {n}'175 // 'new BigNumber() number type has more than 15 significant digits: {n}'
169 ifExceptionsThrow( orig, 0 )176 ifExceptionsThrow( orig, 0 );
170 }177 }
171178
172 // Prevent later check for length on converted number.179 // Prevent later check for length on converted number.
173 isNum = !isNum180 isNum = !isNum;
174 }181 }
175 n = convert( n, 10, b, x['s'] )182 n = convert( n, 10, b, x['s'] );
176183
177 } else if ( n != 'Infinity' && n != 'NaN' ) {184 } else if ( n != 'Infinity' && n != 'NaN' ) {
178185
179 // 'new BigNumber() not a base {b} number: {n}'186 // 'new BigNumber() not a base {b} number: {n}'
180 ifExceptionsThrow( orig, 1, b );187 ifExceptionsThrow( orig, 1, b );
181 n = 'NaN'188 n = 'NaN';
182 }189 }
183 } else {190 } else {
184191
@@ -187,10 +194,10 @@
187 ifExceptionsThrow( b, 2 );194 ifExceptionsThrow( b, 2 );
188195
189 // Ignore base.196 // Ignore base.
190 valid = isValid.test(n)197 valid = isValid.test(n);
191 }198 }
192 } else {199 } else {
193 valid = isValid.test(n)200 valid = isValid.test(n);
194 }201 }
195202
196 if ( !valid ) {203 if ( !valid ) {
@@ -205,19 +212,19 @@
205 if ( n != 'NaN' ) {212 if ( n != 'NaN' ) {
206213
207 // 'new BigNumber() not a number: {n}'214 // 'new BigNumber() not a number: {n}'
208 ifExceptionsThrow( orig, 3 )215 ifExceptionsThrow( orig, 3 );
209 }216 }
210 x['s'] = null217 x['s'] = null;
211 }218 }
212 id = 0;219 id = 0;
213220
214 return221 return;
215 }222 }
216 }223 }
217224
218 // Decimal point?225 // Decimal point?
219 if ( ( e = n.indexOf('.') ) > -1 ) {226 if ( ( e = n.indexOf('.') ) > -1 ) {
220 n = n.replace( '.', '' )227 n = n.replace( '.', '' );
221 }228 }
222229
223 // Exponential form?230 // Exponential form?
@@ -225,15 +232,15 @@
225232
226 // Determine exponent.233 // Determine exponent.
227 if ( e < 0 ) {234 if ( e < 0 ) {
228 e = i235 e = i;
229 }236 }
230 e += +n.slice( i + 1 );237 e += +n.slice( i + 1 );
231 n = n.substring( 0, i )238 n = n.substring( 0, i );
232239
233 } else if ( e < 0 ) {240 } else if ( e < 0 ) {
234241
235 // Integer.242 // Integer.
236 e = n.length243 e = n.length;
237 }244 }
238245
239 // Determine leading zeros.246 // Determine leading zeros.
@@ -242,11 +249,11 @@
242249
243 b = n.length;250 b = n.length;
244251
245 // Disallow numbers with over 11 significant digits if number type.252 // Disallow numbers with over 15 significant digits if number type.
246 if ( isNum && b > 11 && n.slice(i).length > 11 ) {253 if ( isNum && b > 15 && n.slice(i).length > 15 ) {
247254
248 // 'new BigNumber() number type has more than 11 significant digits: {n}'255 // 'new BigNumber() number type has more than 15 significant digits: {n}'
249 ifExceptionsThrow( orig, 0 )256 ifExceptionsThrow( orig, 0 );
250 }257 }
251 id = 0;258 id = 0;
252259
@@ -254,13 +261,13 @@
254 if ( ( e -= i + 1 ) > MAX_EXP ) {261 if ( ( e -= i + 1 ) > MAX_EXP ) {
255262
256 // Infinity.263 // Infinity.
257 x['c'] = x['e'] = null264 x['c'] = x['e'] = null;
258265
259 // Zero or underflow?266 // Zero or underflow?
260 } else if ( i == b || e < MIN_EXP ) {267 } else if ( i == b || e < MIN_EXP ) {
261268
262 // Zero.269 // Zero.
263 x['c'] = [ x['e'] = 0 ]270 x['c'] = [ x['e'] = 0 ];
264 } else {271 } else {
265272
266 // Determine trailing zeros.273 // Determine trailing zeros.
@@ -314,7 +321,7 @@
314 c = 'config',321 c = 'config',
315 inRange = function ( n, lo, hi ) {322 inRange = function ( n, lo, hi ) {
316 return !( ( outOfRange = n < lo || n > hi ) ||323 return !( ( outOfRange = n < lo || n > hi ) ||
317 parse(n) != n && n !== 0 )324 parse(n) != n && n !== 0 );
318 },325 },
319 has = o && typeof o == 'object'326 has = o && typeof o == 'object'
320 ? function () {if ( o.hasOwnProperty(p) ) return ( v = o[p] ) != null}327 ? function () {if ( o.hasOwnProperty(p) ) return ( v = o[p] ) != null}
@@ -324,12 +331,12 @@
324 if ( has( p = 'DECIMAL_PLACES' ) ) {331 if ( has( p = 'DECIMAL_PLACES' ) ) {
325332
326 if ( inRange( v, 0, MAX ) ) {333 if ( inRange( v, 0, MAX ) ) {
327 DECIMAL_PLACES = v | 0334 DECIMAL_PLACES = v | 0;
328 } else {335 } else {
329336
330 // 'config() DECIMAL_PLACES not an integer: {v}'337 // 'config() DECIMAL_PLACES not an integer: {v}'
331 // 'config() DECIMAL_PLACES out of range: {v}'338 // 'config() DECIMAL_PLACES out of range: {v}'
332 ifExceptionsThrow( v, p, c )339 ifExceptionsThrow( v, p, c );
333 }340 }
334 }341 }
335 r[p] = DECIMAL_PLACES;342 r[p] = DECIMAL_PLACES;
@@ -338,12 +345,12 @@
338 if ( has( p = 'ROUNDING_MODE' ) ) {345 if ( has( p = 'ROUNDING_MODE' ) ) {
339346
340 if ( inRange( v, 0, 8 ) ) {347 if ( inRange( v, 0, 8 ) ) {
341 ROUNDING_MODE = v | 0348 ROUNDING_MODE = v | 0;
342 } else {349 } else {
343350
344 // 'config() ROUNDING_MODE not an integer: {v}'351 // 'config() ROUNDING_MODE not an integer: {v}'
345 // 'config() ROUNDING_MODE out of range: {v}'352 // 'config() ROUNDING_MODE out of range: {v}'
346 ifExceptionsThrow( v, p, c )353 ifExceptionsThrow( v, p, c );
347 }354 }
348 }355 }
349 r[p] = ROUNDING_MODE;356 r[p] = ROUNDING_MODE;
@@ -355,15 +362,16 @@
355 if ( has( p = 'EXPONENTIAL_AT' ) ) {362 if ( has( p = 'EXPONENTIAL_AT' ) ) {
356363
357 if ( inRange( v, -MAX, MAX ) ) {364 if ( inRange( v, -MAX, MAX ) ) {
358 TO_EXP_NEG = -( TO_EXP_POS = ~~( v < 0 ? -v : +v ) )365 TO_EXP_NEG = -( TO_EXP_POS = ~~( v < 0 ? -v : +v ) );
359 } else if ( !outOfRange && v && inRange( v[0], -MAX, 0 ) &&366 } else if ( !outOfRange && v && inRange( v[0], -MAX, 0 ) &&
360 inRange( v[1], 0, MAX ) ) {367 inRange( v[1], 0, MAX ) ) {
361 TO_EXP_NEG = ~~v[0], TO_EXP_POS = ~~v[1]368 TO_EXP_NEG = ~~v[0];
369 TO_EXP_POS = ~~v[1];
362 } else {370 } else {
363371
364 // 'config() EXPONENTIAL_AT not an integer or not [integer, integer]: {v}'372 // 'config() EXPONENTIAL_AT not an integer or not [integer, integer]: {v}'
365 // 'config() EXPONENTIAL_AT out of range or not [negative, positive: {v}'373 // 'config() EXPONENTIAL_AT out of range or not [negative, positive: {v}'
366 ifExceptionsThrow( v, p, c, 1 )374 ifExceptionsThrow( v, p, c, 1 );
367 }375 }
368 }376 }
369 r[p] = [ TO_EXP_NEG, TO_EXP_POS ];377 r[p] = [ TO_EXP_NEG, TO_EXP_POS ];
@@ -375,15 +383,15 @@
375 if ( has( p = 'RANGE' ) ) {383 if ( has( p = 'RANGE' ) ) {
376384
377 if ( inRange( v, -MAX, MAX ) && ~~v ) {385 if ( inRange( v, -MAX, MAX ) && ~~v ) {
378 MIN_EXP = -( MAX_EXP = ~~( v < 0 ? -v : +v ) )386 MIN_EXP = -( MAX_EXP = ~~( v < 0 ? -v : +v ) );
379 } else if ( !outOfRange && v && inRange( v[0], -MAX, -1 ) &&387 } else if ( !outOfRange && v && inRange( v[0], -MAX, -1 ) &&
380 inRange( v[1], 1, MAX ) ) {388 inRange( v[1], 1, MAX ) ) {
381 MIN_EXP = ~~v[0], MAX_EXP = ~~v[1]389 MIN_EXP = ~~v[0], MAX_EXP = ~~v[1];
382 } else {390 } else {
383391
384 // 'config() RANGE not a non-zero integer or not [integer, integer]: {v}'392 // 'config() RANGE not a non-zero integer or not [integer, integer]: {v}'
385 // 'config() RANGE out of range or not [negative, positive: {v}'393 // 'config() RANGE out of range or not [negative, positive: {v}'
386 ifExceptionsThrow( v, p, c, 1, 1 )394 ifExceptionsThrow( v, p, c, 1, 1 );
387 }395 }
388 }396 }
389 r[p] = [ MIN_EXP, MAX_EXP ];397 r[p] = [ MIN_EXP, MAX_EXP ];
@@ -394,16 +402,16 @@
394 if ( v === !!v || v === 1 || v === 0 ) {402 if ( v === !!v || v === 1 || v === 0 ) {
395 parse = ( outOfRange = id = 0, ERRORS = !!v )403 parse = ( outOfRange = id = 0, ERRORS = !!v )
396 ? parseInt404 ? parseInt
397 : parseFloat405 : parseFloat;
398 } else {406 } else {
399407
400 // 'config() ERRORS not a boolean or binary digit: {v}'408 // 'config() ERRORS not a boolean or binary digit: {v}'
401 ifExceptionsThrow( v, p, c, 0, 0, 1 )409 ifExceptionsThrow( v, p, c, 0, 0, 1 );
402 }410 }
403 }411 }
404 r[p] = ERRORS;412 r[p] = ERRORS;
405413
406 return r414 return r;
407 };415 };
408416
409417
@@ -422,7 +430,7 @@
422 ( isRange ? ' non-zero' : 'n' ) + ' integer';430 ( isRange ? ' non-zero' : 'n' ) + ' integer';
423431
424 message = ( [432 message = ( [
425 method + ' number type has more than 11 significant digits',433 method + ' number type has more than 15 significant digits',
426 method + ' not a base ' + j + ' number',434 method + ' not a base ' + j + ' number',
427 method + ' base' + message,435 method + ' base' + message,
428 method + ' not a number' ][i] ||436 method + ' not a number' ][i] ||
@@ -438,7 +446,7 @@
438 error = new Error(message);446 error = new Error(message);
439 error['name'] = 'BigNumber Error';447 error['name'] = 'BigNumber Error';
440448
441 throw error449 throw error;
442 }450 }
443 }451 }
444452
@@ -471,15 +479,15 @@
471 if ( arr[j] > baseOut - 1 ) {479 if ( arr[j] > baseOut - 1 ) {
472480
473 if ( arr[j + 1] == null ) {481 if ( arr[j + 1] == null ) {
474 arr[j + 1] = 0482 arr[j + 1] = 0;
475 }483 }
476 arr[j + 1] += arr[j] / baseOut ^ 0;484 arr[j + 1] += arr[j] / baseOut ^ 0;
477 arr[j] %= baseOut485 arr[j] %= baseOut;
478 }486 }
479 }487 }
480 }488 }
481489
482 return arr.reverse()490 return arr.reverse();
483 }491 }
484492
485 // Convert array to string.493 // Convert array to string.
@@ -492,11 +500,11 @@
492 for ( ; i < arrL; str += DIGITS.charAt( arr[i++] ) ) {500 for ( ; i < arrL; str += DIGITS.charAt( arr[i++] ) ) {
493 }501 }
494502
495 return str503 return str;
496 }504 }
497505
498 if ( baseIn < 37 ) {506 if ( baseIn < 37 ) {
499 nStr = nStr.toLowerCase()507 nStr = nStr.toLowerCase();
500 }508 }
501509
502 /*510 /*
@@ -539,7 +547,7 @@
539 }547 }
540548
541 // Append the fraction part to the converted integer part.549 // Append the fraction part to the converted integer part.
542 nStr = arrToStr(nArr) + '.' + arrToStr(fracArr)550 nStr = arrToStr(nArr) + '.' + arrToStr(fracArr);
543551
544 // fracArr is [1].552 // fracArr is [1].
545 // Fraction digits rounded up, so increment last digit of integer part.553 // Fraction digits rounded up, so increment last digit of integer part.
@@ -547,23 +555,23 @@
547555
548 if ( nArr[ e = nArr.length - 1 ] < baseOut - 1 ) {556 if ( nArr[ e = nArr.length - 1 ] < baseOut - 1 ) {
549 ++nArr[e];557 ++nArr[e];
550 nStr = arrToStr(nArr)558 nStr = arrToStr(nArr);
551 } else {559 } else {
552 nStr = new BigNumber( arrToStr(nArr),560 nStr = new BigNumber( arrToStr(nArr),
553 baseOut )['plus'](ONE)['toS'](baseOut)561 baseOut )['plus'](ONE)['toS'](baseOut);
554 }562 }
555563
556 // fracArr is [0]. No fraction digits.564 // fracArr is [0]. No fraction digits.
557 } else {565 } else {
558 nStr = arrToStr(nArr)566 nStr = arrToStr(nArr);
559 }567 }
560 } else {568 } else {
561569
562 // Simple integer. Convert base.570 // Simple integer. Convert base.
563 nStr = arrToStr( strToArr(nStr) )571 nStr = arrToStr( strToArr(nStr) );
564 }572 }
565573
566 return nStr574 return nStr;
567 }575 }
568576
569577
@@ -591,19 +599,18 @@
591 dvsZ.unshift(0);599 dvsZ.unshift(0);
592600
593 do {601 do {
594
595 // 'next' is how many times the divisor goes into the current remainder.602 // 'next' is how many times the divisor goes into the current remainder.
596 for ( next = 0; next < base; next++ ) {603 for ( next = 0; next < base; next++ ) {
597604
598 // Compare divisor and remainder.605 // Compare divisor and remainder.
599 if ( dvsL != ( remL = rem.length ) ) {606 if ( dvsL != ( remL = rem.length ) ) {
600 cmp = dvsL > remL ? 1 : -1607 cmp = dvsL > remL ? 1 : -1;
601 } else {608 } else {
602 for ( remI = -1, cmp = 0; ++remI < dvsL; ) {609 for ( remI = -1, cmp = 0; ++remI < dvsL; ) {
603610
604 if ( dvs[remI] != rem[remI] ) {611 if ( dvs[remI] != rem[remI] ) {
605 cmp = dvs[remI] > rem[remI] ? 1 : -1;612 cmp = dvs[remI] > rem[remI] ? 1 : -1;
606 break613 break;
607 }614 }
608 }615 }
609 }616 }
@@ -622,24 +629,24 @@
622 rem[remI] = base - 1 ) {629 rem[remI] = base - 1 ) {
623 }630 }
624 --rem[remI];631 --rem[remI];
625 rem[remL] += base632 rem[remL] += base;
626 }633 }
627 rem[remL] -= dvsT[remL]634 rem[remL] -= dvsT[remL];
628 }635 }
629 for ( ; !rem[0]; rem.shift() ) {636 for ( ; !rem[0]; rem.shift() ) {
630 }637 }
631 } else {638 } else {
632 break639 break;
633 }640 }
634 }641 }
635642
636 // Add the 'next' digit to the result array.
637 qc[qi++] = cmp ? next : ++next;
638
639 // Update the remainder.643 // Update the remainder.
640 rem[0] && cmp644 rem[0] && cmp
641 ? ( rem[remL] = dvd[dvdI] || 0 )645 ? ( rem[remL] = dvd[dvdI] || 0 )
642 : ( rem = [ dvd[dvdI] ] )646 : ( rem = [ dvd[dvdI] ] );
647
648 // Add the 'next' digit to the result array.
649 qc[qi++] = cmp ? next : ++next;
643650
644 } while ( ( dvdI++ < dvdL || rem[0] != null ) && s-- );651 } while ( ( dvdI++ < dvdL || rem[0] != null ) && s-- );
645652
@@ -648,28 +655,28 @@
648655
649 // There can't be more than one zero.656 // There can't be more than one zero.
650 --quo['e'];657 --quo['e'];
651 qc.shift()658 qc.shift();
652 }659 }
653660
654 // Round?661 // Round?
655 if ( qi > dig ) {662 if ( qi > dig ) {
656 rnd( quo, DECIMAL_PLACES, base, isOdd, rem[0] != null )663 rnd( quo, DECIMAL_PLACES, base, isOdd, rem[0] != null );
657 }664 }
658665
659 // Overflow?666 // Overflow?
660 if ( quo['e'] > MAX_EXP ) {667 if ( quo['e'] > MAX_EXP ) {
661668
662 // Infinity.669 // Infinity.
663 quo['c'] = quo['e'] = null670 quo['c'] = quo['e'] = null;
664671
665 // Underflow?672 // Underflow?
666 } else if ( quo['e'] < MIN_EXP ) {673 } else if ( quo['e'] < MIN_EXP ) {
667674
668 // Zero.675 // Zero.
669 quo['c'] = [quo['e'] = 0]676 quo['c'] = [quo['e'] = 0];
670 }677 }
671678
672 return quo679 return quo;
673 }680 }
674681
675682
@@ -689,12 +696,12 @@
689696
690 // +-Infinity or NaN?697 // +-Infinity or NaN?
691 if ( !c ) {698 if ( !c ) {
692 return n['toS']()699 return n['toS']();
693 }700 }
694701
695 // Round?702 // Round?
696 if ( c.length > ++d ) {703 if ( c.length > ++d ) {
697 rnd( n, i, 10 )704 rnd( n, i, 10 );
698 }705 }
699706
700 // Recalculate d if toFixed as n['e'] may have changed if value rounded up.707 // Recalculate d if toFixed as n['e'] may have changed if value rounded up.
@@ -718,7 +725,7 @@
718 : c[0] ) + ( i < 0 ? 'e' : 'e+' ) + i725 : c[0] ) + ( i < 0 ? 'e' : 'e+' ) + i
719726
720 // Normal notation.727 // Normal notation.
721 : n['toS']()728 : n['toS']();
722 }729 }
723730
724731
@@ -768,14 +775,14 @@
768775
769 // 1, 0.1, 0.01, 0.001, 0.0001 etc.776 // 1, 0.1, 0.01, 0.001, 0.0001 etc.
770 xc[0] = 1;777 xc[0] = 1;
771 x['e'] = -dp778 x['e'] = -dp;
772 } else {779 } else {
773780
774 // Zero.781 // Zero.
775 x['e'] = 0782 x['e'] = 0;
776 }783 }
777784
778 return x785 return x;
779 }786 }
780787
781 // Remove any digits after the required decimal places.788 // Remove any digits after the required decimal places.
@@ -790,7 +797,7 @@
790797
791 if ( !i-- ) {798 if ( !i-- ) {
792 ++x['e'];799 ++x['e'];
793 xc.unshift(1)800 xc.unshift(1);
794 }801 }
795 }802 }
796 }803 }
@@ -799,7 +806,7 @@
799 for ( i = xc.length; !xc[--i]; xc.pop() ) {806 for ( i = xc.length; !xc[--i]; xc.pop() ) {
800 }807 }
801808
802 return x809 return x;
803 }810 }
804811
805812
@@ -813,7 +820,7 @@
813 x['c'] && rnd( x, dp, 10 );820 x['c'] && rnd( x, dp, 10 );
814 ROUNDING_MODE = r;821 ROUNDING_MODE = r;
815822
816 return x823 return x;
817 }824 }
818825
819826
@@ -827,10 +834,10 @@
827 var x = new BigNumber(this);834 var x = new BigNumber(this);
828835
829 if ( x['s'] < 0 ) {836 if ( x['s'] < 0 ) {
830 x['s'] = 1837 x['s'] = 1;
831 }838 }
832839
833 return x840 return x;
834 };841 };
835842
836843
@@ -839,7 +846,7 @@
839 * rounded to a whole number in the direction of Infinity.846 * rounded to a whole number in the direction of Infinity.
840 */847 */
841 P['ceil'] = function () {848 P['ceil'] = function () {
842 return setMode( this, 0, 2 )849 return setMode( this, 0, 2 );
843 };850 };
844851
845852
@@ -862,29 +869,29 @@
862869
863 // Either NaN?870 // Either NaN?
864 if ( !i || !j ) {871 if ( !i || !j ) {
865 return null872 return null;
866 }873 }
867874
868 a = xc && !xc[0], b = yc && !yc[0];875 a = xc && !xc[0], b = yc && !yc[0];
869876
870 // Either zero?877 // Either zero?
871 if ( a || b ) {878 if ( a || b ) {
872 return a ? b ? 0 : -j : i879 return a ? b ? 0 : -j : i;
873 }880 }
874881
875 // Signs differ?882 // Signs differ?
876 if ( i != j ) {883 if ( i != j ) {
877 return i884 return i;
878 }885 }
879886
880 // Either Infinity?887 // Either Infinity?
881 if ( a = i < 0, b = k == l, !xc || !yc ) {888 if ( a = i < 0, b = k == l, !xc || !yc ) {
882 return b ? 0 : !xc ^ a ? 1 : -1889 return b ? 0 : !xc ^ a ? 1 : -1;
883 }890 }
884891
885 // Compare exponents.892 // Compare exponents.
886 if ( !b ) {893 if ( !b ) {
887 return k > l ^ a ? 1 : -1894 return k > l ^ a ? 1 : -1;
888 }895 }
889896
890 // Compare digit by digit.897 // Compare digit by digit.
@@ -893,11 +900,11 @@
893 ++i < j; ) {900 ++i < j; ) {
894901
895 if ( xc[i] != yc[i] ) {902 if ( xc[i] != yc[i] ) {
896 return xc[i] > yc[i] ^ a ? 1 : -1903 return xc[i] > yc[i] ^ a ? 1 : -1;
897 }904 }
898 }905 }
899 // Compare lengths.906 // Compare lengths.
900 return k == l ? 0 : k > l ^ a ? 1 : -1907 return k == l ? 0 : k > l ^ a ? 1 : -1;
901 };908 };
902909
903910
@@ -952,7 +959,7 @@
952 // y is 0. Return +-Infinity.959 // y is 0. Return +-Infinity.
953 : s / 0 )960 : s / 0 )
954961
955 : divide( xc, yc, xe - ye, s, 10 )962 : divide( xc, yc, xe - ye, s, 10 );
956 };963 };
957964
958965
@@ -962,7 +969,7 @@
962 */969 */
963 P['equals'] = P['eq'] = function ( n, b ) {970 P['equals'] = P['eq'] = function ( n, b ) {
964 id = 3;971 id = 3;
965 return this['cmp']( n, b ) === 0972 return this['cmp']( n, b ) === 0;
966 };973 };
967974
968975
@@ -971,7 +978,7 @@
971 * rounded to a whole number in the direction of -Infinity.978 * rounded to a whole number in the direction of -Infinity.
972 */979 */
973 P['floor'] = function () {980 P['floor'] = function () {
974 return setMode( this, 0, 3 )981 return setMode( this, 0, 3 );
975 };982 };
976983
977984
@@ -981,7 +988,7 @@
981 */988 */
982 P['greaterThan'] = P['gt'] = function ( n, b ) {989 P['greaterThan'] = P['gt'] = function ( n, b ) {
983 id = 4;990 id = 4;
984 return this['cmp']( n, b ) > 0991 return this['cmp']( n, b ) > 0;
985 };992 };
986993
987994
@@ -991,7 +998,7 @@
991 */998 */
992 P['greaterThanOrEqualTo'] = P['gte'] = function ( n, b ) {999 P['greaterThanOrEqualTo'] = P['gte'] = function ( n, b ) {
993 id = 5;1000 id = 5;
994 return ( b = this['cmp']( n, b ) ) == 1 || b === 01001 return ( b = this['cmp']( n, b ) ) == 1 || b === 0;
995 };1002 };
9961003
9971004
@@ -1000,7 +1007,7 @@
1000 * returns false.1007 * returns false.
1001 */1008 */
1002 P['isFinite'] = P['isF'] = function () {1009 P['isFinite'] = P['isF'] = function () {
1003 return !!this['c']1010 return !!this['c'];
1004 };1011 };
10051012
10061013
@@ -1009,7 +1016,7 @@
1009 * false.1016 * false.
1010 */1017 */
1011 P['isNaN'] = function () {1018 P['isNaN'] = function () {
1012 return !this['s']1019 return !this['s'];
1013 };1020 };
10141021
10151022
@@ -1018,7 +1025,7 @@
1018 * returns false.1025 * returns false.
1019 */1026 */
1020 P['isNegative'] = P['isNeg'] = function () {1027 P['isNegative'] = P['isNeg'] = function () {
1021 return this['s'] < 01028 return this['s'] < 0;
1022 };1029 };
10231030
10241031
@@ -1027,7 +1034,7 @@
1027 * false.1034 * false.
1028 */1035 */
1029 P['isZero'] = P['isZ'] = function () {1036 P['isZero'] = P['isZ'] = function () {
1030 return !!this['c'] && this['c'][0] == 01037 return !!this['c'] && this['c'][0] == 0;
1031 };1038 };
10321039
10331040
@@ -1037,7 +1044,7 @@
1037 */1044 */
1038 P['lessThan'] = P['lt'] = function ( n, b ) {1045 P['lessThan'] = P['lt'] = function ( n, b ) {
1039 id = 6;1046 id = 6;
1040 return this['cmp']( n, b ) < 01047 return this['cmp']( n, b ) < 0;
1041 };1048 };
10421049
10431050
@@ -1047,7 +1054,7 @@
1047 */1054 */
1048 P['lessThanOrEqualTo'] = P['lte'] = function ( n, b ) {1055 P['lessThanOrEqualTo'] = P['lte'] = function ( n, b ) {
1049 id = 7;1056 id = 7;
1050 return ( b = this['cmp']( n, b ) ) == -1 || b === 01057 return ( b = this['cmp']( n, b ) ) == -1 || b === 0;
1051 };1058 };
10521059
10531060
@@ -1080,12 +1087,12 @@
10801087
1081 // Either NaN?1088 // Either NaN?
1082 if ( !a || !b ) {1089 if ( !a || !b ) {
1083 return new BigNumber(NaN)1090 return new BigNumber(NaN);
1084 }1091 }
10851092
1086 // Signs differ?1093 // Signs differ?
1087 if ( a != b ) {1094 if ( a != b ) {
1088 return y['s'] = -b, x['plus'](y)1095 return y['s'] = -b, x['plus'](y);
1089 }1096 }
10901097
1091 var xc = x['c'],1098 var xc = x['c'],
@@ -1097,7 +1104,7 @@
10971104
1098 // Either Infinity?1105 // Either Infinity?
1099 if ( !xc || !yc ) {1106 if ( !xc || !yc ) {
1100 return xc ? ( y['s'] = -b, y ) : new BigNumber( yc ? x : NaN )1107 return xc ? ( y['s'] = -b, y ) : new BigNumber( yc ? x : NaN );
1101 }1108 }
11021109
1103 // Either zero?1110 // Either zero?
@@ -1113,7 +1120,7 @@
11131120
1114 // Both are zero.1121 // Both are zero.
1115 // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity1122 // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity
1116 : ROUNDING_MODE == 3 ? -0 : 0 )1123 : ROUNDING_MODE == 3 ? -0 : 0 );
1117 }1124 }
1118 }1125 }
11191126
@@ -1124,7 +1131,7 @@
11241131
1125 for ( d.reverse(), b = a; b--; d.push(0) ) {1132 for ( d.reverse(), b = a; b--; d.push(0) ) {
1126 }1133 }
1127 d.reverse()1134 d.reverse();
1128 } else {1135 } else {
11291136
1130 // Exponents equal. Check digit by digit.1137 // Exponents equal. Check digit by digit.
@@ -1134,7 +1141,7 @@
11341141
1135 if ( xc[b] != yc[b] ) {1142 if ( xc[b] != yc[b] ) {
1136 xLTy = xc[b] < yc[b];1143 xLTy = xc[b] < yc[b];
1137 break1144 break;
1138 }1145 }
1139 }1146 }
1140 }1147 }
@@ -1142,7 +1149,7 @@
1142 // x < y? Point xc to the array of the bigger number.1149 // x < y? Point xc to the array of the bigger number.
1143 if ( xLTy ) {1150 if ( xLTy ) {
1144 d = xc, xc = yc, yc = d;1151 d = xc, xc = yc, yc = d;
1145 y['s'] = -y['s']1152 y['s'] = -y['s'];
1146 }1153 }
11471154
1148 /*1155 /*
@@ -1163,9 +1170,9 @@
1163 for ( i = b; i && !xc[--i]; xc[i] = 9 ) {1170 for ( i = b; i && !xc[--i]; xc[i] = 9 ) {
1164 }1171 }
1165 --xc[i];1172 --xc[i];
1166 xc[b] += 101173 xc[b] += 10;
1167 }1174 }
1168 xc[b] -= yc[b]1175 xc[b] -= yc[b];
1169 }1176 }
11701177
1171 // Remove trailing zeros.1178 // Remove trailing zeros.
@@ -1189,14 +1196,14 @@
1189 * n - n = +0 but n - n = -0 when rounding towards -Infinity.1196 * n - n = +0 but n - n = -0 when rounding towards -Infinity.
1190 */1197 */
1191 if ( !xc[0] ) {1198 if ( !xc[0] ) {
1192 y['s'] = ROUNDING_MODE == 3 ? -1 : 11199 y['s'] = ROUNDING_MODE == 3 ? -1 : 1;
1193 }1200 }
11941201
1195 // Result is zero.1202 // Result is zero.
1196 xc = [ye = 0]1203 xc = [ye = 0];
1197 }1204 }
11981205
1199 return y['c'] = xc, y['e'] = ye, y1206 return y['c'] = xc, y['e'] = ye, y;
1200 };1207 };
12011208
12021209
@@ -1225,7 +1232,7 @@
1225 b = !i || !j || yc && !yc[0];1232 b = !i || !j || yc && !yc[0];
12261233
1227 if ( b || xc && !xc[0] ) {1234 if ( b || xc && !xc[0] ) {
1228 return new BigNumber( b ? NaN : x )1235 return new BigNumber( b ? NaN : x );
1229 }1236 }
12301237
1231 x['s'] = y['s'] = 1;1238 x['s'] = y['s'] = 1;
@@ -1238,7 +1245,7 @@
1238 DECIMAL_PLACES = 0, ROUNDING_MODE = 1,1245 DECIMAL_PLACES = 0, ROUNDING_MODE = 1,
1239 x = x['div'](y),1246 x = x['div'](y),
1240 DECIMAL_PLACES = i, ROUNDING_MODE = j,1247 DECIMAL_PLACES = i, ROUNDING_MODE = j,
1241 this['minus']( x['times'](y) ) )1248 this['minus']( x['times'](y) ) );
1242 };1249 };
12431250
12441251
@@ -1249,7 +1256,7 @@
1249 P['negated'] = P['neg'] = function () {1256 P['negated'] = P['neg'] = function () {
1250 var x = new BigNumber(this);1257 var x = new BigNumber(this);
12511258
1252 return x['s'] = -x['s'] || null, x1259 return x['s'] = -x['s'] || null, x;
1253 };1260 };
12541261
12551262
@@ -1282,12 +1289,12 @@
12821289
1283 // Either NaN?1290 // Either NaN?
1284 if ( !a || !b ) {1291 if ( !a || !b ) {
1285 return new BigNumber(NaN)1292 return new BigNumber(NaN);
1286 }1293 }
12871294
1288 // Signs differ?1295 // Signs differ?
1289 if ( a != b ) {1296 if ( a != b ) {
1290 return y['s'] = -b, x['minus'](y)1297 return y['s'] = -b, x['minus'](y);
1291 }1298 }
12921299
1293 var xe = x['e'],1300 var xe = x['e'],
@@ -1301,7 +1308,7 @@
1301 if ( !xc || !yc ) {1308 if ( !xc || !yc ) {
13021309
1303 // Return +-Infinity.1310 // Return +-Infinity.
1304 return new BigNumber( a / 0 )1311 return new BigNumber( a / 0 );
1305 }1312 }
13061313
1307 // Either zero?1314 // Either zero?
@@ -1316,7 +1323,7 @@
1316 ? x1323 ? x
13171324
1318 // Both are zero. Return zero.1325 // Both are zero. Return zero.
1319 : a * 0 )1326 : a * 0 );
1320 }1327 }
1321 }1328 }
13221329
@@ -1327,12 +1334,12 @@
13271334
1328 for ( d.reverse(); a--; d.push(0) ) {1335 for ( d.reverse(); a--; d.push(0) ) {
1329 }1336 }
1330 d.reverse()1337 d.reverse();
1331 }1338 }
13321339
1333 // Point xc to the longer array.1340 // Point xc to the longer array.
1334 if ( xc.length - yc.length < 0 ) {1341 if ( xc.length - yc.length < 0 ) {
1335 d = yc, yc = xc, xc = d1342 d = yc, yc = xc, xc = d;
1336 }1343 }
13371344
1338 /*1345 /*
@@ -1352,7 +1359,7 @@
1352 if ( ++ye > MAX_EXP ) {1359 if ( ++ye > MAX_EXP ) {
13531360
1354 // Infinity.1361 // Infinity.
1355 xc = ye = null1362 xc = ye = null;
1356 }1363 }
1357 }1364 }
13581365
@@ -1360,7 +1367,7 @@
1360 for ( a = xc.length; xc[--a] == 0; xc.pop() ) {1367 for ( a = xc.length; xc[--a] == 0; xc.pop() ) {
1361 }1368 }
13621369
1363 return y['c'] = xc, y['e'] = ye, y1370 return y['c'] = xc, y['e'] = ye, y;
1364 };1371 };
13651372
13661373
@@ -1399,23 +1406,23 @@
1399 !i ) {1406 !i ) {
14001407
1401 // i is +-Infinity, NaN or 0.1408 // i is +-Infinity, NaN or 0.
1402 return new BigNumber( Math.pow( x['toS'](), i ) )1409 return new BigNumber( Math.pow( x['toS'](), i ) );
1403 }1410 }
14041411
1405 for ( i = i < 0 ? -i : i; ; ) {1412 for ( i = i < 0 ? -i : i; ; ) {
14061413
1407 if ( i & 1 ) {1414 if ( i & 1 ) {
1408 y = y['times'](x)1415 y = y['times'](x);
1409 }1416 }
1410 i >>= 1;1417 i >>= 1;
14111418
1412 if ( !i ) {1419 if ( !i ) {
1413 break1420 break;
1414 }1421 }
1415 x = x['times'](x)1422 x = x['times'](x);
1416 }1423 }
14171424
1418 return e < 0 ? ONE['div'](y) : y1425 return e < 0 ? ONE['div'](y) : y;
1419 };1426 };
14201427
14211428
@@ -1449,7 +1456,7 @@
1449 ? ROUNDING_MODE1456 ? ROUNDING_MODE
1450 : rm | 0;1457 : rm | 0;
14511458
1452 return setMode( this, dp, rm )1459 return setMode( this, dp, rm );
1453 };1460 };
14541461
14551462
@@ -1465,7 +1472,7 @@
1465 * this BigNumber, rounded according to DECIMAL_PLACES and ROUNDING_MODE.1472 * this BigNumber, rounded according to DECIMAL_PLACES and ROUNDING_MODE.
1466 */1473 */
1467 P['squareRoot'] = P['sqrt'] = function () {1474 P['squareRoot'] = P['sqrt'] = function () {
1468 var i, n, r, re, t,1475 var n, r, re, t,
1469 x = this,1476 x = this,
1470 c = x['c'],1477 c = x['c'],
1471 s = x['s'],1478 s = x['s'],
@@ -1479,7 +1486,7 @@
14791486
1480 return new BigNumber( !s || s < 0 && ( !c || c[0] )1487 return new BigNumber( !s || s < 0 && ( !c || c[0] )
1481 ? NaN1488 ? NaN
1482 : c ? x : 1 / 0 )1489 : c ? x : 1 / 0 );
1483 }1490 }
14841491
1485 // Initial estimate.1492 // Initial estimate.
@@ -1494,23 +1501,23 @@
1494 n = c.join('');1501 n = c.join('');
14951502
1496 if ( !( n.length + e & 1 ) ) {1503 if ( !( n.length + e & 1 ) ) {
1497 n += '0'1504 n += '0';
1498 }1505 }
1499 r = new BigNumber( Math.sqrt(n) + '' );1506 r = new BigNumber( Math.sqrt(n) + '' );
15001507
1501 // r may still not be finite.1508 // r may still not be finite.
1502 if ( !r['c'] ) {1509 if ( !r['c'] ) {
1503 r['c'] = [1]1510 r['c'] = [1];
1504 }1511 }
1505 r['e'] = ( ( ( e + 1 ) / 2 ) | 0 ) - ( e < 0 || e & 1 )1512 r['e'] = ( ( ( e + 1 ) / 2 ) | 0 ) - ( e < 0 || e & 1 );
1506 } else {1513 } else {
1507 r = new BigNumber( n = s.toString() )1514 r = new BigNumber( n = s.toString() );
1508 }1515 }
1509 re = r['e'];1516 re = r['e'];
1510 s = re + ( DECIMAL_PLACES += 4 );1517 s = re + ( DECIMAL_PLACES += 4 );
15111518
1512 if ( s < 3 ) {1519 if ( s < 3 ) {
1513 s = 01520 s = 0;
1514 }1521 }
1515 e = s;1522 e = s;
15161523
@@ -1548,12 +1555,12 @@
1548 ROUNDING_MODE = rm;1555 ROUNDING_MODE = rm;
1549 DECIMAL_PLACES = dp;1556 DECIMAL_PLACES = dp;
15501557
1551 return t1558 return t;
1552 }1559 }
1553 }1560 }
1554 DECIMAL_PLACES += 4;1561 DECIMAL_PLACES += 4;
1555 s += 4;1562 s += 4;
1556 n = ''1563 n = '';
1557 } else {1564 } else {
15581565
1559 /*1566 /*
@@ -1566,21 +1573,21 @@
15661573
1567 // Truncate to the first rounding digit.1574 // Truncate to the first rounding digit.
1568 if ( c.length > e - 2 ) {1575 if ( c.length > e - 2 ) {
1569 c.length = e - 21576 c.length = e - 2;
1570 }1577 }
15711578
1572 if ( !r['times'](r)['eq'](x) ) {1579 if ( !r['times'](r)['eq'](x) ) {
15731580
1574 while ( c.length < e - 3 ) {1581 while ( c.length < e - 3 ) {
1575 c.push(0)1582 c.push(0);
1576 }1583 }
1577 c[e - 3]++1584 c[e - 3]++;
1578 }1585 }
1579 }1586 }
1580 ROUNDING_MODE = rm;1587 ROUNDING_MODE = rm;
1581 rnd( r, DECIMAL_PLACES = dp, 10 );1588 rnd( r, DECIMAL_PLACES = dp, 10 );
15821589
1583 return r1590 return r;
1584 }1591 }
1585 }1592 }
1586 }1593 }
@@ -1637,12 +1644,12 @@
1637 ? y['s'] / 01644 ? y['s'] / 0
16381645
1639 // x or y is 0. Return +-0.1646 // x or y is 0. Return +-0.
1640 : y['s'] * 0 )1647 : y['s'] * 0 );
1641 }1648 }
1642 y['e'] = i + j;1649 y['e'] = i + j;
16431650
1644 if ( ( a = xc.length ) < ( b = yc.length ) ) {1651 if ( ( a = xc.length ) < ( b = yc.length ) ) {
1645 c = xc, xc = yc, yc = c, j = a, a = b, b = j1652 c = xc, xc = yc, yc = c, j = a, a = b, b = j;
1646 }1653 }
16471654
1648 for ( j = a + b, c = []; j--; c.push(0) ) {1655 for ( j = a + b, c = []; j--; c.push(0) ) {
@@ -1659,7 +1666,7 @@
1659 }1666 }
16601667
1661 if ( b ) {1668 if ( b ) {
1662 c[j] = ( c[j] + b ) % 101669 c[j] = ( c[j] + b ) % 10;
1663 }1670 }
1664 }1671 }
16651672
@@ -1689,7 +1696,7 @@
1689 // Neither.1696 // Neither.
1690 : c;1697 : c;
16911698
1692 return y1699 return y;
1693 };1700 };
16941701
16951702
@@ -1715,7 +1722,7 @@
1715 // 'toE() decimal places out of range: {dp}'1722 // 'toE() decimal places out of range: {dp}'
1716 !ifExceptionsThrow( dp, 'decimal places', 'toE' ) ) && this['c']1723 !ifExceptionsThrow( dp, 'decimal places', 'toE' ) ) && this['c']
1717 ? this['c'].length - 11724 ? this['c'].length - 1
1718 : dp | 0, 1 )1725 : dp | 0, 1 );
1719 };1726 };
17201727
17211728
@@ -1739,7 +1746,7 @@
1739 // 'toF() decimal places not an integer: {dp}'1746 // 'toF() decimal places not an integer: {dp}'
1740 // 'toF() decimal places out of range: {dp}'1747 // 'toF() decimal places out of range: {dp}'
1741 !ifExceptionsThrow( dp, 'decimal places', 'toF' ) ) ) {1748 !ifExceptionsThrow( dp, 'decimal places', 'toF' ) ) ) {
1742 d = x['e'] + ( dp | 0 )1749 d = x['e'] + ( dp | 0 );
1743 }1750 }
17441751
1745 n = TO_EXP_NEG, dp = TO_EXP_POS;1752 n = TO_EXP_NEG, dp = TO_EXP_POS;
@@ -1747,7 +1754,7 @@
17471754
1748 // Note: str is initially undefined.1755 // Note: str is initially undefined.
1749 if ( d == str ) {1756 if ( d == str ) {
1750 str = x['toS']()1757 str = x['toS']();
1751 } else {1758 } else {
1752 str = format( x, d );1759 str = format( x, d );
17531760
@@ -1757,17 +1764,17 @@
17571764
1758 // As e.g. -0 toFixed(3), will wrongly be returned as -0.000 from toString.1765 // As e.g. -0 toFixed(3), will wrongly be returned as -0.000 from toString.
1759 if ( !x['c'][0] ) {1766 if ( !x['c'][0] ) {
1760 str = str.replace(/^-/, '')1767 str = str.replace(/^-/, '');
17611768
1762 // As e.g. -0.5 if rounded to -0 will cause toString to omit the minus sign.1769 // As e.g. -0.5 if rounded to -0 will cause toString to omit the minus sign.
1763 } else if ( str.indexOf('-') < 0 ) {1770 } else if ( str.indexOf('-') < 0 ) {
1764 str = '-' + str1771 str = '-' + str;
1765 }1772 }
1766 }1773 }
1767 }1774 }
1768 TO_EXP_NEG = n, TO_EXP_POS = dp;1775 TO_EXP_NEG = n, TO_EXP_POS = dp;
17691776
1770 return str1777 return str;
1771 };1778 };
17721779
17731780
@@ -1794,7 +1801,7 @@
17941801
1795 // NaN, Infinity.1802 // NaN, Infinity.
1796 if ( !xc ) {1803 if ( !xc ) {
1797 return x['toS']()1804 return x['toS']();
1798 }1805 }
17991806
1800 e = d['e'] = xc.length - x['e'] - 1;1807 e = d['e'] = xc.length - x['e'] - 1;
@@ -1819,7 +1826,7 @@
1819 ( maxD = n )['cmp'](d) > 0 ) {1826 ( maxD = n )['cmp'](d) > 0 ) {
18201827
1821 // d is e.g. 10, 100, 1000, 10000... , n1 is 1.1828 // d is e.g. 10, 100, 1000, 10000... , n1 is 1.
1822 maxD = e > 0 ? d : n11829 maxD = e > 0 ? d : n1;
1823 }1830 }
18241831
1825 MAX_EXP = 1 / 0;1832 MAX_EXP = 1 / 0;
@@ -1830,7 +1837,7 @@
1830 d2 = d0['plus']( q['times'](d1) );1837 d2 = d0['plus']( q['times'](d1) );
18311838
1832 if ( d2['cmp'](maxD) == 1 ) {1839 if ( d2['cmp'](maxD) == 1 ) {
1833 break1840 break;
1834 }1841 }
18351842
1836 d0 = d1, d1 = d2;1843 d0 = d1, d1 = d2;
@@ -1839,7 +1846,7 @@
1839 n0 = d2;1846 n0 = d2;
18401847
1841 d = n['minus']( q['times']( d2 = d ) );1848 d = n['minus']( q['times']( d2 = d ) );
1842 n = d21849 n = d2;
1843 }1850 }
18441851
1845 d2 = maxD['minus'](d0)['div'](d1);1852 d2 = maxD['minus'](d0)['div'](d1);
@@ -1857,7 +1864,7 @@
1857 ? [ n1['toS'](), d1['toS']() ]1864 ? [ n1['toS'](), d1['toS']() ]
1858 : [ n0['toS'](), d0['toS']() ];1865 : [ n0['toS'](), d0['toS']() ];
18591866
1860 return MAX_EXP = exp, DECIMAL_PLACES = dp, frac1867 return MAX_EXP = exp, DECIMAL_PLACES = dp, frac;
1861 };1868 };
18621869
18631870
@@ -1883,7 +1890,7 @@
1883 // 'toP() precision out of range: {sd}'1890 // 'toP() precision out of range: {sd}'
1884 !ifExceptionsThrow( sd, 'precision', 'toP' ) )1891 !ifExceptionsThrow( sd, 'precision', 'toP' ) )
1885 ? this['toS']()1892 ? this['toS']()
1886 : format( this, --sd | 0, 2 )1893 : format( this, --sd | 0, 2 );
1887 };1894 };
18881895
18891896
@@ -1904,11 +1911,11 @@
19041911
1905 // Infinity or NaN?1912 // Infinity or NaN?
1906 if ( xe === null ) {1913 if ( xe === null ) {
1907 str = x['s'] ? 'Infinity' : 'NaN'1914 str = x['s'] ? 'Infinity' : 'NaN';
19081915
1909 // Exponential format?1916 // Exponential format?
1910 } else if ( b === u && ( xe <= TO_EXP_NEG || xe >= TO_EXP_POS ) ) {1917 } else if ( b === u && ( xe <= TO_EXP_NEG || xe >= TO_EXP_POS ) ) {
1911 return format( x, x['c'].length - 1, 1 )1918 return format( x, x['c'].length - 1, 1 );
1912 } else {1919 } else {
1913 str = x['c'].join('');1920 str = x['c'].join('');
19141921
@@ -1918,7 +1925,7 @@
1918 // Prepend zeros.1925 // Prepend zeros.
1919 for ( ; ++xe; str = '0' + str ) {1926 for ( ; ++xe; str = '0' + str ) {
1920 }1927 }
1921 str = '0.' + str1928 str = '0.' + str;
19221929
1923 // Positive exponent?1930 // Positive exponent?
1924 } else if ( strL = str.length, xe > 0 ) {1931 } else if ( strL = str.length, xe > 0 ) {
@@ -1929,17 +1936,17 @@
1929 for ( xe -= strL; xe-- ; str += '0' ) {1936 for ( xe -= strL; xe-- ; str += '0' ) {
1930 }1937 }
1931 } else if ( xe < strL ) {1938 } else if ( xe < strL ) {
1932 str = str.slice( 0, xe ) + '.' + str.slice(xe)1939 str = str.slice( 0, xe ) + '.' + str.slice(xe);
1933 }1940 }
19341941
1935 // Exponent zero.1942 // Exponent zero.
1936 } else {1943 } else {
1937 if ( u = str.charAt(0), strL > 1 ) {1944 if ( u = str.charAt(0), strL > 1 ) {
1938 str = u + '.' + str.slice(1)1945 str = u + '.' + str.slice(1);
19391946
1940 // Avoid '-0'1947 // Avoid '-0'
1941 } else if ( u == '0' ) {1948 } else if ( u == '0' ) {
1942 return u1949 return u;
1943 }1950 }
1944 }1951 }
19451952
@@ -1951,19 +1958,31 @@
19511958
1952 // Avoid '-0'1959 // Avoid '-0'
1953 if ( str == '0' ) {1960 if ( str == '0' ) {
1954 return str1961 return str;
1955 }1962 }
1956 } else {1963 } else {
19571964
1958 // 'toS() base not an integer: {b}'1965 // 'toS() base not an integer: {b}'
1959 // 'toS() base out of range: {b}'1966 // 'toS() base out of range: {b}'
1960 ifExceptionsThrow( b, 'base', 'toS' )1967 ifExceptionsThrow( b, 'base', 'toS' );
1961 }1968 }
1962 }1969 }
19631970
1964 }1971 }
19651972
1966 return x['s'] < 0 ? '-' + str : str1973 return x['s'] < 0 ? '-' + str : str;
1974 };
1975
1976
1977 /*
1978 * Return the value of this BigNumber converted to a number primitive.
1979 *
1980 */
1981 P['toNumber'] = P['toN'] = function () {
1982 var x = this;
1983
1984 // Ensure zero has correct sign.
1985 return +x || ( x['s'] ? 0 * x['s'] : NaN );
1967 };1986 };
19681987
19691988
@@ -1971,7 +1990,7 @@
1971 * Return as toString, but do not accept a base argument.1990 * Return as toString, but do not accept a base argument.
1972 */1991 */
1973 P['valueOf'] = function () {1992 P['valueOf'] = function () {
1974 return this['toS']()1993 return this['toS']();
1975 };1994 };
19761995
19771996
@@ -1990,13 +2009,13 @@
19902009
1991 // Node and other CommonJS-like environments that support module.exports.2010 // Node and other CommonJS-like environments that support module.exports.
1992 if ( typeof module !== 'undefined' && module.exports ) {2011 if ( typeof module !== 'undefined' && module.exports ) {
1993 module.exports = BigNumber2012 module.exports = BigNumber;
19942013
1995 //AMD.2014 //AMD.
1996 } else if ( typeof define == 'function' && define.amd ) {2015 } else if ( typeof define == 'function' && define.amd ) {
1997 define( function () {2016 define( function () {
1998 return BigNumber2017 return BigNumber;
1999 })2018 });
20002019
2001 //Browser.2020 //Browser.
2002 } else {2021 } else {
@@ -2004,4 +2023,3 @@
2004 }2023 }
20052024
2006})( this );2025})( this );
2007

Subscribers

People subscribed via source and target branches