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
1=== modified file 'bignumber.js'
2--- bignumber.js 2014-04-26 17:59:39 +0000
3+++ bignumber.js 2014-07-02 14:22:11 +0000
4@@ -1,12 +1,19 @@
5-/* bignumber.js v1.3.0 https://github.com/MikeMcl/bignumber.js/LICENCE */
6+/*! bignumber.js v1.4.1 https://github.com/MikeMcl/bignumber.js/LICENCE */
7
8 var BN;
9
10+/* Due bug https://bugs.launchpad.net/ubuntu-calculator-app/+bug/1332567
11+ * there is a change after line 598, remember to add it when you update
12+ * the file
13+ * See
14+ * https://code.launchpad.net/~vthompson/ubuntu-calculator-app/test-fix-1332567
15+ */
16+
17 ;(function ( global ) {
18 'use strict';
19
20 /*
21- bignumber.js v1.3.0
22+ bignumber.js v1.4.1
23 A JavaScript library for arbitrary-precision arithmetic.
24 https://github.com/MikeMcl/bignumber.js
25 Copyright (c) 2012 Michael Mclaughlin <M8ch88l@gmail.com>
26@@ -114,7 +121,7 @@
27 x['s'] = n['s'];
28 x['e'] = n['e'];
29 x['c'] = ( n = n['c'] ) ? n.slice() : n;
30- return
31+ return;
32 }
33 }
34
35@@ -122,7 +129,7 @@
36 if ( typeof n != 'string' ) {
37 n = ( isNum = typeof n == 'number' ||
38 Object.prototype.toString.call(n) == '[object Number]' ) &&
39- n === 0 && 1 / n < 0 ? '-0' : n + ''
40+ n === 0 && 1 / n < 0 ? '-0' : n + '';
41 }
42
43 orig = n;
44@@ -130,7 +137,7 @@
45 if ( b === e && isValid.test(n) ) {
46
47 // Determine sign.
48- x['s'] = n.charAt(0) == '-' ? ( n = n.slice(1), -1 ) : 1
49+ x['s'] = n.charAt(0) == '-' ? ( n = n.slice(1), -1 ) : 1;
50
51 // Either n is not a valid BigNumber or a base has been specified.
52 } else {
53@@ -139,7 +146,7 @@
54 // Ensure return value is rounded to DECIMAL_PLACES as with other bases.
55 if ( b == 10 ) {
56
57- return setMode( n, DECIMAL_PLACES, ROUNDING_MODE )
58+ return setMode( n, DECIMAL_PLACES, ROUNDING_MODE );
59 }
60
61 n = trim.call(n).replace( /^\+(?!-)/, '' );
62@@ -163,22 +170,22 @@
63
64 if ( isNum ) {
65
66- if ( n.replace( /^0\.0*|\./, '' ).length > 11 ) {
67+ if ( n.replace( /^0\.0*|\./, '' ).length > 15 ) {
68
69- // 'new BigNumber() number type has more than 11 significant digits: {n}'
70- ifExceptionsThrow( orig, 0 )
71+ // 'new BigNumber() number type has more than 15 significant digits: {n}'
72+ ifExceptionsThrow( orig, 0 );
73 }
74
75 // Prevent later check for length on converted number.
76- isNum = !isNum
77+ isNum = !isNum;
78 }
79- n = convert( n, 10, b, x['s'] )
80+ n = convert( n, 10, b, x['s'] );
81
82 } else if ( n != 'Infinity' && n != 'NaN' ) {
83
84 // 'new BigNumber() not a base {b} number: {n}'
85 ifExceptionsThrow( orig, 1, b );
86- n = 'NaN'
87+ n = 'NaN';
88 }
89 } else {
90
91@@ -187,10 +194,10 @@
92 ifExceptionsThrow( b, 2 );
93
94 // Ignore base.
95- valid = isValid.test(n)
96+ valid = isValid.test(n);
97 }
98 } else {
99- valid = isValid.test(n)
100+ valid = isValid.test(n);
101 }
102
103 if ( !valid ) {
104@@ -205,19 +212,19 @@
105 if ( n != 'NaN' ) {
106
107 // 'new BigNumber() not a number: {n}'
108- ifExceptionsThrow( orig, 3 )
109+ ifExceptionsThrow( orig, 3 );
110 }
111- x['s'] = null
112+ x['s'] = null;
113 }
114 id = 0;
115
116- return
117+ return;
118 }
119 }
120
121 // Decimal point?
122 if ( ( e = n.indexOf('.') ) > -1 ) {
123- n = n.replace( '.', '' )
124+ n = n.replace( '.', '' );
125 }
126
127 // Exponential form?
128@@ -225,15 +232,15 @@
129
130 // Determine exponent.
131 if ( e < 0 ) {
132- e = i
133+ e = i;
134 }
135 e += +n.slice( i + 1 );
136- n = n.substring( 0, i )
137+ n = n.substring( 0, i );
138
139 } else if ( e < 0 ) {
140
141 // Integer.
142- e = n.length
143+ e = n.length;
144 }
145
146 // Determine leading zeros.
147@@ -242,11 +249,11 @@
148
149 b = n.length;
150
151- // Disallow numbers with over 11 significant digits if number type.
152- if ( isNum && b > 11 && n.slice(i).length > 11 ) {
153+ // Disallow numbers with over 15 significant digits if number type.
154+ if ( isNum && b > 15 && n.slice(i).length > 15 ) {
155
156- // 'new BigNumber() number type has more than 11 significant digits: {n}'
157- ifExceptionsThrow( orig, 0 )
158+ // 'new BigNumber() number type has more than 15 significant digits: {n}'
159+ ifExceptionsThrow( orig, 0 );
160 }
161 id = 0;
162
163@@ -254,13 +261,13 @@
164 if ( ( e -= i + 1 ) > MAX_EXP ) {
165
166 // Infinity.
167- x['c'] = x['e'] = null
168+ x['c'] = x['e'] = null;
169
170 // Zero or underflow?
171 } else if ( i == b || e < MIN_EXP ) {
172
173 // Zero.
174- x['c'] = [ x['e'] = 0 ]
175+ x['c'] = [ x['e'] = 0 ];
176 } else {
177
178 // Determine trailing zeros.
179@@ -314,7 +321,7 @@
180 c = 'config',
181 inRange = function ( n, lo, hi ) {
182 return !( ( outOfRange = n < lo || n > hi ) ||
183- parse(n) != n && n !== 0 )
184+ parse(n) != n && n !== 0 );
185 },
186 has = o && typeof o == 'object'
187 ? function () {if ( o.hasOwnProperty(p) ) return ( v = o[p] ) != null}
188@@ -324,12 +331,12 @@
189 if ( has( p = 'DECIMAL_PLACES' ) ) {
190
191 if ( inRange( v, 0, MAX ) ) {
192- DECIMAL_PLACES = v | 0
193+ DECIMAL_PLACES = v | 0;
194 } else {
195
196 // 'config() DECIMAL_PLACES not an integer: {v}'
197 // 'config() DECIMAL_PLACES out of range: {v}'
198- ifExceptionsThrow( v, p, c )
199+ ifExceptionsThrow( v, p, c );
200 }
201 }
202 r[p] = DECIMAL_PLACES;
203@@ -338,12 +345,12 @@
204 if ( has( p = 'ROUNDING_MODE' ) ) {
205
206 if ( inRange( v, 0, 8 ) ) {
207- ROUNDING_MODE = v | 0
208+ ROUNDING_MODE = v | 0;
209 } else {
210
211 // 'config() ROUNDING_MODE not an integer: {v}'
212 // 'config() ROUNDING_MODE out of range: {v}'
213- ifExceptionsThrow( v, p, c )
214+ ifExceptionsThrow( v, p, c );
215 }
216 }
217 r[p] = ROUNDING_MODE;
218@@ -355,15 +362,16 @@
219 if ( has( p = 'EXPONENTIAL_AT' ) ) {
220
221 if ( inRange( v, -MAX, MAX ) ) {
222- TO_EXP_NEG = -( TO_EXP_POS = ~~( v < 0 ? -v : +v ) )
223+ TO_EXP_NEG = -( TO_EXP_POS = ~~( v < 0 ? -v : +v ) );
224 } else if ( !outOfRange && v && inRange( v[0], -MAX, 0 ) &&
225 inRange( v[1], 0, MAX ) ) {
226- TO_EXP_NEG = ~~v[0], TO_EXP_POS = ~~v[1]
227+ TO_EXP_NEG = ~~v[0];
228+ TO_EXP_POS = ~~v[1];
229 } else {
230
231 // 'config() EXPONENTIAL_AT not an integer or not [integer, integer]: {v}'
232 // 'config() EXPONENTIAL_AT out of range or not [negative, positive: {v}'
233- ifExceptionsThrow( v, p, c, 1 )
234+ ifExceptionsThrow( v, p, c, 1 );
235 }
236 }
237 r[p] = [ TO_EXP_NEG, TO_EXP_POS ];
238@@ -375,15 +383,15 @@
239 if ( has( p = 'RANGE' ) ) {
240
241 if ( inRange( v, -MAX, MAX ) && ~~v ) {
242- MIN_EXP = -( MAX_EXP = ~~( v < 0 ? -v : +v ) )
243+ MIN_EXP = -( MAX_EXP = ~~( v < 0 ? -v : +v ) );
244 } else if ( !outOfRange && v && inRange( v[0], -MAX, -1 ) &&
245 inRange( v[1], 1, MAX ) ) {
246- MIN_EXP = ~~v[0], MAX_EXP = ~~v[1]
247+ MIN_EXP = ~~v[0], MAX_EXP = ~~v[1];
248 } else {
249
250 // 'config() RANGE not a non-zero integer or not [integer, integer]: {v}'
251 // 'config() RANGE out of range or not [negative, positive: {v}'
252- ifExceptionsThrow( v, p, c, 1, 1 )
253+ ifExceptionsThrow( v, p, c, 1, 1 );
254 }
255 }
256 r[p] = [ MIN_EXP, MAX_EXP ];
257@@ -394,16 +402,16 @@
258 if ( v === !!v || v === 1 || v === 0 ) {
259 parse = ( outOfRange = id = 0, ERRORS = !!v )
260 ? parseInt
261- : parseFloat
262+ : parseFloat;
263 } else {
264
265 // 'config() ERRORS not a boolean or binary digit: {v}'
266- ifExceptionsThrow( v, p, c, 0, 0, 1 )
267+ ifExceptionsThrow( v, p, c, 0, 0, 1 );
268 }
269 }
270 r[p] = ERRORS;
271
272- return r
273+ return r;
274 };
275
276
277@@ -422,7 +430,7 @@
278 ( isRange ? ' non-zero' : 'n' ) + ' integer';
279
280 message = ( [
281- method + ' number type has more than 11 significant digits',
282+ method + ' number type has more than 15 significant digits',
283 method + ' not a base ' + j + ' number',
284 method + ' base' + message,
285 method + ' not a number' ][i] ||
286@@ -438,7 +446,7 @@
287 error = new Error(message);
288 error['name'] = 'BigNumber Error';
289
290- throw error
291+ throw error;
292 }
293 }
294
295@@ -471,15 +479,15 @@
296 if ( arr[j] > baseOut - 1 ) {
297
298 if ( arr[j + 1] == null ) {
299- arr[j + 1] = 0
300+ arr[j + 1] = 0;
301 }
302 arr[j + 1] += arr[j] / baseOut ^ 0;
303- arr[j] %= baseOut
304+ arr[j] %= baseOut;
305 }
306 }
307 }
308
309- return arr.reverse()
310+ return arr.reverse();
311 }
312
313 // Convert array to string.
314@@ -492,11 +500,11 @@
315 for ( ; i < arrL; str += DIGITS.charAt( arr[i++] ) ) {
316 }
317
318- return str
319+ return str;
320 }
321
322 if ( baseIn < 37 ) {
323- nStr = nStr.toLowerCase()
324+ nStr = nStr.toLowerCase();
325 }
326
327 /*
328@@ -539,7 +547,7 @@
329 }
330
331 // Append the fraction part to the converted integer part.
332- nStr = arrToStr(nArr) + '.' + arrToStr(fracArr)
333+ nStr = arrToStr(nArr) + '.' + arrToStr(fracArr);
334
335 // fracArr is [1].
336 // Fraction digits rounded up, so increment last digit of integer part.
337@@ -547,23 +555,23 @@
338
339 if ( nArr[ e = nArr.length - 1 ] < baseOut - 1 ) {
340 ++nArr[e];
341- nStr = arrToStr(nArr)
342+ nStr = arrToStr(nArr);
343 } else {
344 nStr = new BigNumber( arrToStr(nArr),
345- baseOut )['plus'](ONE)['toS'](baseOut)
346+ baseOut )['plus'](ONE)['toS'](baseOut);
347 }
348
349 // fracArr is [0]. No fraction digits.
350 } else {
351- nStr = arrToStr(nArr)
352+ nStr = arrToStr(nArr);
353 }
354 } else {
355
356 // Simple integer. Convert base.
357- nStr = arrToStr( strToArr(nStr) )
358+ nStr = arrToStr( strToArr(nStr) );
359 }
360
361- return nStr
362+ return nStr;
363 }
364
365
366@@ -591,19 +599,18 @@
367 dvsZ.unshift(0);
368
369 do {
370-
371 // 'next' is how many times the divisor goes into the current remainder.
372 for ( next = 0; next < base; next++ ) {
373
374 // Compare divisor and remainder.
375 if ( dvsL != ( remL = rem.length ) ) {
376- cmp = dvsL > remL ? 1 : -1
377+ cmp = dvsL > remL ? 1 : -1;
378 } else {
379 for ( remI = -1, cmp = 0; ++remI < dvsL; ) {
380
381 if ( dvs[remI] != rem[remI] ) {
382 cmp = dvs[remI] > rem[remI] ? 1 : -1;
383- break
384+ break;
385 }
386 }
387 }
388@@ -622,24 +629,24 @@
389 rem[remI] = base - 1 ) {
390 }
391 --rem[remI];
392- rem[remL] += base
393+ rem[remL] += base;
394 }
395- rem[remL] -= dvsT[remL]
396+ rem[remL] -= dvsT[remL];
397 }
398 for ( ; !rem[0]; rem.shift() ) {
399 }
400 } else {
401- break
402+ break;
403 }
404 }
405
406- // Add the 'next' digit to the result array.
407- qc[qi++] = cmp ? next : ++next;
408-
409 // Update the remainder.
410 rem[0] && cmp
411 ? ( rem[remL] = dvd[dvdI] || 0 )
412- : ( rem = [ dvd[dvdI] ] )
413+ : ( rem = [ dvd[dvdI] ] );
414+
415+ // Add the 'next' digit to the result array.
416+ qc[qi++] = cmp ? next : ++next;
417
418 } while ( ( dvdI++ < dvdL || rem[0] != null ) && s-- );
419
420@@ -648,28 +655,28 @@
421
422 // There can't be more than one zero.
423 --quo['e'];
424- qc.shift()
425+ qc.shift();
426 }
427
428 // Round?
429 if ( qi > dig ) {
430- rnd( quo, DECIMAL_PLACES, base, isOdd, rem[0] != null )
431+ rnd( quo, DECIMAL_PLACES, base, isOdd, rem[0] != null );
432 }
433
434 // Overflow?
435 if ( quo['e'] > MAX_EXP ) {
436
437 // Infinity.
438- quo['c'] = quo['e'] = null
439+ quo['c'] = quo['e'] = null;
440
441 // Underflow?
442 } else if ( quo['e'] < MIN_EXP ) {
443
444 // Zero.
445- quo['c'] = [quo['e'] = 0]
446+ quo['c'] = [quo['e'] = 0];
447 }
448
449- return quo
450+ return quo;
451 }
452
453
454@@ -689,12 +696,12 @@
455
456 // +-Infinity or NaN?
457 if ( !c ) {
458- return n['toS']()
459+ return n['toS']();
460 }
461
462 // Round?
463 if ( c.length > ++d ) {
464- rnd( n, i, 10 )
465+ rnd( n, i, 10 );
466 }
467
468 // Recalculate d if toFixed as n['e'] may have changed if value rounded up.
469@@ -718,7 +725,7 @@
470 : c[0] ) + ( i < 0 ? 'e' : 'e+' ) + i
471
472 // Normal notation.
473- : n['toS']()
474+ : n['toS']();
475 }
476
477
478@@ -768,14 +775,14 @@
479
480 // 1, 0.1, 0.01, 0.001, 0.0001 etc.
481 xc[0] = 1;
482- x['e'] = -dp
483+ x['e'] = -dp;
484 } else {
485
486 // Zero.
487- x['e'] = 0
488+ x['e'] = 0;
489 }
490
491- return x
492+ return x;
493 }
494
495 // Remove any digits after the required decimal places.
496@@ -790,7 +797,7 @@
497
498 if ( !i-- ) {
499 ++x['e'];
500- xc.unshift(1)
501+ xc.unshift(1);
502 }
503 }
504 }
505@@ -799,7 +806,7 @@
506 for ( i = xc.length; !xc[--i]; xc.pop() ) {
507 }
508
509- return x
510+ return x;
511 }
512
513
514@@ -813,7 +820,7 @@
515 x['c'] && rnd( x, dp, 10 );
516 ROUNDING_MODE = r;
517
518- return x
519+ return x;
520 }
521
522
523@@ -827,10 +834,10 @@
524 var x = new BigNumber(this);
525
526 if ( x['s'] < 0 ) {
527- x['s'] = 1
528+ x['s'] = 1;
529 }
530
531- return x
532+ return x;
533 };
534
535
536@@ -839,7 +846,7 @@
537 * rounded to a whole number in the direction of Infinity.
538 */
539 P['ceil'] = function () {
540- return setMode( this, 0, 2 )
541+ return setMode( this, 0, 2 );
542 };
543
544
545@@ -862,29 +869,29 @@
546
547 // Either NaN?
548 if ( !i || !j ) {
549- return null
550+ return null;
551 }
552
553 a = xc && !xc[0], b = yc && !yc[0];
554
555 // Either zero?
556 if ( a || b ) {
557- return a ? b ? 0 : -j : i
558+ return a ? b ? 0 : -j : i;
559 }
560
561 // Signs differ?
562 if ( i != j ) {
563- return i
564+ return i;
565 }
566
567 // Either Infinity?
568 if ( a = i < 0, b = k == l, !xc || !yc ) {
569- return b ? 0 : !xc ^ a ? 1 : -1
570+ return b ? 0 : !xc ^ a ? 1 : -1;
571 }
572
573 // Compare exponents.
574 if ( !b ) {
575- return k > l ^ a ? 1 : -1
576+ return k > l ^ a ? 1 : -1;
577 }
578
579 // Compare digit by digit.
580@@ -893,11 +900,11 @@
581 ++i < j; ) {
582
583 if ( xc[i] != yc[i] ) {
584- return xc[i] > yc[i] ^ a ? 1 : -1
585+ return xc[i] > yc[i] ^ a ? 1 : -1;
586 }
587 }
588 // Compare lengths.
589- return k == l ? 0 : k > l ^ a ? 1 : -1
590+ return k == l ? 0 : k > l ^ a ? 1 : -1;
591 };
592
593
594@@ -952,7 +959,7 @@
595 // y is 0. Return +-Infinity.
596 : s / 0 )
597
598- : divide( xc, yc, xe - ye, s, 10 )
599+ : divide( xc, yc, xe - ye, s, 10 );
600 };
601
602
603@@ -962,7 +969,7 @@
604 */
605 P['equals'] = P['eq'] = function ( n, b ) {
606 id = 3;
607- return this['cmp']( n, b ) === 0
608+ return this['cmp']( n, b ) === 0;
609 };
610
611
612@@ -971,7 +978,7 @@
613 * rounded to a whole number in the direction of -Infinity.
614 */
615 P['floor'] = function () {
616- return setMode( this, 0, 3 )
617+ return setMode( this, 0, 3 );
618 };
619
620
621@@ -981,7 +988,7 @@
622 */
623 P['greaterThan'] = P['gt'] = function ( n, b ) {
624 id = 4;
625- return this['cmp']( n, b ) > 0
626+ return this['cmp']( n, b ) > 0;
627 };
628
629
630@@ -991,7 +998,7 @@
631 */
632 P['greaterThanOrEqualTo'] = P['gte'] = function ( n, b ) {
633 id = 5;
634- return ( b = this['cmp']( n, b ) ) == 1 || b === 0
635+ return ( b = this['cmp']( n, b ) ) == 1 || b === 0;
636 };
637
638
639@@ -1000,7 +1007,7 @@
640 * returns false.
641 */
642 P['isFinite'] = P['isF'] = function () {
643- return !!this['c']
644+ return !!this['c'];
645 };
646
647
648@@ -1009,7 +1016,7 @@
649 * false.
650 */
651 P['isNaN'] = function () {
652- return !this['s']
653+ return !this['s'];
654 };
655
656
657@@ -1018,7 +1025,7 @@
658 * returns false.
659 */
660 P['isNegative'] = P['isNeg'] = function () {
661- return this['s'] < 0
662+ return this['s'] < 0;
663 };
664
665
666@@ -1027,7 +1034,7 @@
667 * false.
668 */
669 P['isZero'] = P['isZ'] = function () {
670- return !!this['c'] && this['c'][0] == 0
671+ return !!this['c'] && this['c'][0] == 0;
672 };
673
674
675@@ -1037,7 +1044,7 @@
676 */
677 P['lessThan'] = P['lt'] = function ( n, b ) {
678 id = 6;
679- return this['cmp']( n, b ) < 0
680+ return this['cmp']( n, b ) < 0;
681 };
682
683
684@@ -1047,7 +1054,7 @@
685 */
686 P['lessThanOrEqualTo'] = P['lte'] = function ( n, b ) {
687 id = 7;
688- return ( b = this['cmp']( n, b ) ) == -1 || b === 0
689+ return ( b = this['cmp']( n, b ) ) == -1 || b === 0;
690 };
691
692
693@@ -1080,12 +1087,12 @@
694
695 // Either NaN?
696 if ( !a || !b ) {
697- return new BigNumber(NaN)
698+ return new BigNumber(NaN);
699 }
700
701 // Signs differ?
702 if ( a != b ) {
703- return y['s'] = -b, x['plus'](y)
704+ return y['s'] = -b, x['plus'](y);
705 }
706
707 var xc = x['c'],
708@@ -1097,7 +1104,7 @@
709
710 // Either Infinity?
711 if ( !xc || !yc ) {
712- return xc ? ( y['s'] = -b, y ) : new BigNumber( yc ? x : NaN )
713+ return xc ? ( y['s'] = -b, y ) : new BigNumber( yc ? x : NaN );
714 }
715
716 // Either zero?
717@@ -1113,7 +1120,7 @@
718
719 // Both are zero.
720 // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity
721- : ROUNDING_MODE == 3 ? -0 : 0 )
722+ : ROUNDING_MODE == 3 ? -0 : 0 );
723 }
724 }
725
726@@ -1124,7 +1131,7 @@
727
728 for ( d.reverse(), b = a; b--; d.push(0) ) {
729 }
730- d.reverse()
731+ d.reverse();
732 } else {
733
734 // Exponents equal. Check digit by digit.
735@@ -1134,7 +1141,7 @@
736
737 if ( xc[b] != yc[b] ) {
738 xLTy = xc[b] < yc[b];
739- break
740+ break;
741 }
742 }
743 }
744@@ -1142,7 +1149,7 @@
745 // x < y? Point xc to the array of the bigger number.
746 if ( xLTy ) {
747 d = xc, xc = yc, yc = d;
748- y['s'] = -y['s']
749+ y['s'] = -y['s'];
750 }
751
752 /*
753@@ -1163,9 +1170,9 @@
754 for ( i = b; i && !xc[--i]; xc[i] = 9 ) {
755 }
756 --xc[i];
757- xc[b] += 10
758+ xc[b] += 10;
759 }
760- xc[b] -= yc[b]
761+ xc[b] -= yc[b];
762 }
763
764 // Remove trailing zeros.
765@@ -1189,14 +1196,14 @@
766 * n - n = +0 but n - n = -0 when rounding towards -Infinity.
767 */
768 if ( !xc[0] ) {
769- y['s'] = ROUNDING_MODE == 3 ? -1 : 1
770+ y['s'] = ROUNDING_MODE == 3 ? -1 : 1;
771 }
772
773 // Result is zero.
774- xc = [ye = 0]
775+ xc = [ye = 0];
776 }
777
778- return y['c'] = xc, y['e'] = ye, y
779+ return y['c'] = xc, y['e'] = ye, y;
780 };
781
782
783@@ -1225,7 +1232,7 @@
784 b = !i || !j || yc && !yc[0];
785
786 if ( b || xc && !xc[0] ) {
787- return new BigNumber( b ? NaN : x )
788+ return new BigNumber( b ? NaN : x );
789 }
790
791 x['s'] = y['s'] = 1;
792@@ -1238,7 +1245,7 @@
793 DECIMAL_PLACES = 0, ROUNDING_MODE = 1,
794 x = x['div'](y),
795 DECIMAL_PLACES = i, ROUNDING_MODE = j,
796- this['minus']( x['times'](y) ) )
797+ this['minus']( x['times'](y) ) );
798 };
799
800
801@@ -1249,7 +1256,7 @@
802 P['negated'] = P['neg'] = function () {
803 var x = new BigNumber(this);
804
805- return x['s'] = -x['s'] || null, x
806+ return x['s'] = -x['s'] || null, x;
807 };
808
809
810@@ -1282,12 +1289,12 @@
811
812 // Either NaN?
813 if ( !a || !b ) {
814- return new BigNumber(NaN)
815+ return new BigNumber(NaN);
816 }
817
818 // Signs differ?
819 if ( a != b ) {
820- return y['s'] = -b, x['minus'](y)
821+ return y['s'] = -b, x['minus'](y);
822 }
823
824 var xe = x['e'],
825@@ -1301,7 +1308,7 @@
826 if ( !xc || !yc ) {
827
828 // Return +-Infinity.
829- return new BigNumber( a / 0 )
830+ return new BigNumber( a / 0 );
831 }
832
833 // Either zero?
834@@ -1316,7 +1323,7 @@
835 ? x
836
837 // Both are zero. Return zero.
838- : a * 0 )
839+ : a * 0 );
840 }
841 }
842
843@@ -1327,12 +1334,12 @@
844
845 for ( d.reverse(); a--; d.push(0) ) {
846 }
847- d.reverse()
848+ d.reverse();
849 }
850
851 // Point xc to the longer array.
852 if ( xc.length - yc.length < 0 ) {
853- d = yc, yc = xc, xc = d
854+ d = yc, yc = xc, xc = d;
855 }
856
857 /*
858@@ -1352,7 +1359,7 @@
859 if ( ++ye > MAX_EXP ) {
860
861 // Infinity.
862- xc = ye = null
863+ xc = ye = null;
864 }
865 }
866
867@@ -1360,7 +1367,7 @@
868 for ( a = xc.length; xc[--a] == 0; xc.pop() ) {
869 }
870
871- return y['c'] = xc, y['e'] = ye, y
872+ return y['c'] = xc, y['e'] = ye, y;
873 };
874
875
876@@ -1399,23 +1406,23 @@
877 !i ) {
878
879 // i is +-Infinity, NaN or 0.
880- return new BigNumber( Math.pow( x['toS'](), i ) )
881+ return new BigNumber( Math.pow( x['toS'](), i ) );
882 }
883
884 for ( i = i < 0 ? -i : i; ; ) {
885
886 if ( i & 1 ) {
887- y = y['times'](x)
888+ y = y['times'](x);
889 }
890 i >>= 1;
891
892 if ( !i ) {
893- break
894+ break;
895 }
896- x = x['times'](x)
897+ x = x['times'](x);
898 }
899
900- return e < 0 ? ONE['div'](y) : y
901+ return e < 0 ? ONE['div'](y) : y;
902 };
903
904
905@@ -1449,7 +1456,7 @@
906 ? ROUNDING_MODE
907 : rm | 0;
908
909- return setMode( this, dp, rm )
910+ return setMode( this, dp, rm );
911 };
912
913
914@@ -1465,7 +1472,7 @@
915 * this BigNumber, rounded according to DECIMAL_PLACES and ROUNDING_MODE.
916 */
917 P['squareRoot'] = P['sqrt'] = function () {
918- var i, n, r, re, t,
919+ var n, r, re, t,
920 x = this,
921 c = x['c'],
922 s = x['s'],
923@@ -1479,7 +1486,7 @@
924
925 return new BigNumber( !s || s < 0 && ( !c || c[0] )
926 ? NaN
927- : c ? x : 1 / 0 )
928+ : c ? x : 1 / 0 );
929 }
930
931 // Initial estimate.
932@@ -1494,23 +1501,23 @@
933 n = c.join('');
934
935 if ( !( n.length + e & 1 ) ) {
936- n += '0'
937+ n += '0';
938 }
939 r = new BigNumber( Math.sqrt(n) + '' );
940
941 // r may still not be finite.
942 if ( !r['c'] ) {
943- r['c'] = [1]
944+ r['c'] = [1];
945 }
946- r['e'] = ( ( ( e + 1 ) / 2 ) | 0 ) - ( e < 0 || e & 1 )
947+ r['e'] = ( ( ( e + 1 ) / 2 ) | 0 ) - ( e < 0 || e & 1 );
948 } else {
949- r = new BigNumber( n = s.toString() )
950+ r = new BigNumber( n = s.toString() );
951 }
952 re = r['e'];
953 s = re + ( DECIMAL_PLACES += 4 );
954
955 if ( s < 3 ) {
956- s = 0
957+ s = 0;
958 }
959 e = s;
960
961@@ -1548,12 +1555,12 @@
962 ROUNDING_MODE = rm;
963 DECIMAL_PLACES = dp;
964
965- return t
966+ return t;
967 }
968 }
969 DECIMAL_PLACES += 4;
970 s += 4;
971- n = ''
972+ n = '';
973 } else {
974
975 /*
976@@ -1566,21 +1573,21 @@
977
978 // Truncate to the first rounding digit.
979 if ( c.length > e - 2 ) {
980- c.length = e - 2
981+ c.length = e - 2;
982 }
983
984 if ( !r['times'](r)['eq'](x) ) {
985
986 while ( c.length < e - 3 ) {
987- c.push(0)
988+ c.push(0);
989 }
990- c[e - 3]++
991+ c[e - 3]++;
992 }
993 }
994 ROUNDING_MODE = rm;
995 rnd( r, DECIMAL_PLACES = dp, 10 );
996
997- return r
998+ return r;
999 }
1000 }
1001 }
1002@@ -1637,12 +1644,12 @@
1003 ? y['s'] / 0
1004
1005 // x or y is 0. Return +-0.
1006- : y['s'] * 0 )
1007+ : y['s'] * 0 );
1008 }
1009 y['e'] = i + j;
1010
1011 if ( ( a = xc.length ) < ( b = yc.length ) ) {
1012- c = xc, xc = yc, yc = c, j = a, a = b, b = j
1013+ c = xc, xc = yc, yc = c, j = a, a = b, b = j;
1014 }
1015
1016 for ( j = a + b, c = []; j--; c.push(0) ) {
1017@@ -1659,7 +1666,7 @@
1018 }
1019
1020 if ( b ) {
1021- c[j] = ( c[j] + b ) % 10
1022+ c[j] = ( c[j] + b ) % 10;
1023 }
1024 }
1025
1026@@ -1689,7 +1696,7 @@
1027 // Neither.
1028 : c;
1029
1030- return y
1031+ return y;
1032 };
1033
1034
1035@@ -1715,7 +1722,7 @@
1036 // 'toE() decimal places out of range: {dp}'
1037 !ifExceptionsThrow( dp, 'decimal places', 'toE' ) ) && this['c']
1038 ? this['c'].length - 1
1039- : dp | 0, 1 )
1040+ : dp | 0, 1 );
1041 };
1042
1043
1044@@ -1739,7 +1746,7 @@
1045 // 'toF() decimal places not an integer: {dp}'
1046 // 'toF() decimal places out of range: {dp}'
1047 !ifExceptionsThrow( dp, 'decimal places', 'toF' ) ) ) {
1048- d = x['e'] + ( dp | 0 )
1049+ d = x['e'] + ( dp | 0 );
1050 }
1051
1052 n = TO_EXP_NEG, dp = TO_EXP_POS;
1053@@ -1747,7 +1754,7 @@
1054
1055 // Note: str is initially undefined.
1056 if ( d == str ) {
1057- str = x['toS']()
1058+ str = x['toS']();
1059 } else {
1060 str = format( x, d );
1061
1062@@ -1757,17 +1764,17 @@
1063
1064 // As e.g. -0 toFixed(3), will wrongly be returned as -0.000 from toString.
1065 if ( !x['c'][0] ) {
1066- str = str.replace(/^-/, '')
1067+ str = str.replace(/^-/, '');
1068
1069 // As e.g. -0.5 if rounded to -0 will cause toString to omit the minus sign.
1070 } else if ( str.indexOf('-') < 0 ) {
1071- str = '-' + str
1072+ str = '-' + str;
1073 }
1074 }
1075 }
1076 TO_EXP_NEG = n, TO_EXP_POS = dp;
1077
1078- return str
1079+ return str;
1080 };
1081
1082
1083@@ -1794,7 +1801,7 @@
1084
1085 // NaN, Infinity.
1086 if ( !xc ) {
1087- return x['toS']()
1088+ return x['toS']();
1089 }
1090
1091 e = d['e'] = xc.length - x['e'] - 1;
1092@@ -1819,7 +1826,7 @@
1093 ( maxD = n )['cmp'](d) > 0 ) {
1094
1095 // d is e.g. 10, 100, 1000, 10000... , n1 is 1.
1096- maxD = e > 0 ? d : n1
1097+ maxD = e > 0 ? d : n1;
1098 }
1099
1100 MAX_EXP = 1 / 0;
1101@@ -1830,7 +1837,7 @@
1102 d2 = d0['plus']( q['times'](d1) );
1103
1104 if ( d2['cmp'](maxD) == 1 ) {
1105- break
1106+ break;
1107 }
1108
1109 d0 = d1, d1 = d2;
1110@@ -1839,7 +1846,7 @@
1111 n0 = d2;
1112
1113 d = n['minus']( q['times']( d2 = d ) );
1114- n = d2
1115+ n = d2;
1116 }
1117
1118 d2 = maxD['minus'](d0)['div'](d1);
1119@@ -1857,7 +1864,7 @@
1120 ? [ n1['toS'](), d1['toS']() ]
1121 : [ n0['toS'](), d0['toS']() ];
1122
1123- return MAX_EXP = exp, DECIMAL_PLACES = dp, frac
1124+ return MAX_EXP = exp, DECIMAL_PLACES = dp, frac;
1125 };
1126
1127
1128@@ -1883,7 +1890,7 @@
1129 // 'toP() precision out of range: {sd}'
1130 !ifExceptionsThrow( sd, 'precision', 'toP' ) )
1131 ? this['toS']()
1132- : format( this, --sd | 0, 2 )
1133+ : format( this, --sd | 0, 2 );
1134 };
1135
1136
1137@@ -1904,11 +1911,11 @@
1138
1139 // Infinity or NaN?
1140 if ( xe === null ) {
1141- str = x['s'] ? 'Infinity' : 'NaN'
1142+ str = x['s'] ? 'Infinity' : 'NaN';
1143
1144 // Exponential format?
1145 } else if ( b === u && ( xe <= TO_EXP_NEG || xe >= TO_EXP_POS ) ) {
1146- return format( x, x['c'].length - 1, 1 )
1147+ return format( x, x['c'].length - 1, 1 );
1148 } else {
1149 str = x['c'].join('');
1150
1151@@ -1918,7 +1925,7 @@
1152 // Prepend zeros.
1153 for ( ; ++xe; str = '0' + str ) {
1154 }
1155- str = '0.' + str
1156+ str = '0.' + str;
1157
1158 // Positive exponent?
1159 } else if ( strL = str.length, xe > 0 ) {
1160@@ -1929,17 +1936,17 @@
1161 for ( xe -= strL; xe-- ; str += '0' ) {
1162 }
1163 } else if ( xe < strL ) {
1164- str = str.slice( 0, xe ) + '.' + str.slice(xe)
1165+ str = str.slice( 0, xe ) + '.' + str.slice(xe);
1166 }
1167
1168 // Exponent zero.
1169 } else {
1170 if ( u = str.charAt(0), strL > 1 ) {
1171- str = u + '.' + str.slice(1)
1172+ str = u + '.' + str.slice(1);
1173
1174 // Avoid '-0'
1175 } else if ( u == '0' ) {
1176- return u
1177+ return u;
1178 }
1179 }
1180
1181@@ -1951,19 +1958,31 @@
1182
1183 // Avoid '-0'
1184 if ( str == '0' ) {
1185- return str
1186+ return str;
1187 }
1188 } else {
1189
1190 // 'toS() base not an integer: {b}'
1191 // 'toS() base out of range: {b}'
1192- ifExceptionsThrow( b, 'base', 'toS' )
1193+ ifExceptionsThrow( b, 'base', 'toS' );
1194 }
1195 }
1196
1197 }
1198
1199- return x['s'] < 0 ? '-' + str : str
1200+ return x['s'] < 0 ? '-' + str : str;
1201+ };
1202+
1203+
1204+ /*
1205+ * Return the value of this BigNumber converted to a number primitive.
1206+ *
1207+ */
1208+ P['toNumber'] = P['toN'] = function () {
1209+ var x = this;
1210+
1211+ // Ensure zero has correct sign.
1212+ return +x || ( x['s'] ? 0 * x['s'] : NaN );
1213 };
1214
1215
1216@@ -1971,7 +1990,7 @@
1217 * Return as toString, but do not accept a base argument.
1218 */
1219 P['valueOf'] = function () {
1220- return this['toS']()
1221+ return this['toS']();
1222 };
1223
1224
1225@@ -1990,13 +2009,13 @@
1226
1227 // Node and other CommonJS-like environments that support module.exports.
1228 if ( typeof module !== 'undefined' && module.exports ) {
1229- module.exports = BigNumber
1230+ module.exports = BigNumber;
1231
1232 //AMD.
1233 } else if ( typeof define == 'function' && define.amd ) {
1234 define( function () {
1235- return BigNumber
1236- })
1237+ return BigNumber;
1238+ });
1239
1240 //Browser.
1241 } else {
1242@@ -2004,4 +2023,3 @@
1243 }
1244
1245 })( this );
1246-

Subscribers

People subscribed via source and target branches