64 CPCalculationNoError = 0;
71 @
typedef CPRoundingMode
120 var matches =
string.match(
new RegExp(
"^([+\\-]?)((?:0|[0-9]\\d*)?)(?:\\.(\\d*))?(?:[eE]([+\\-]?)(\\d+))?$"));
126 intpart = matches[2],
127 decpart = matches[3],
133 if (ds && ds ===
"-")
139 exponent = parseInt(exp) * ((es && es ===
"-")?-1:1);
142 exponent -= decpart.length;
144 var inputlength = (intpart?intpart.length:0) + (decpart?decpart.length:0);
151 else if (inputlength === 0)
163 for (; i < (intpart?intpart.length:0); i++)
167 Array.prototype.push.call(m, parseInt(intpart.charAt(i)));
172 for (; j < (decpart?decpart.length:0); j++)
177 Array.prototype.push.call(m, parseInt(decpart.charAt(j)));
180 var dcm = {_exponent:exponent, _isNegative:isNegative, _isCompact:NO, _isNaN:NO, _mantissa:m};
201 mantissa = ABS(mantissa);
205 Array.prototype.push.call(m, 0);
213 Array.prototype.unshift.call(m, parseInt(mantissa % 10));
214 mantissa = FLOOR(mantissa / 10);
217 var dcm = {_exponent:exponent, _isNegative:isNegative, _isCompact:YES, _isNaN:NO, _mantissa:m};
258 function _CPDecimalMakeMaximum()
268 function _CPDecimalMakeMinimum()
288 for (var i = 0; i < dcm._mantissa.length; i++)
289 if (dcm._mantissa[i] !== 0)
310 if (dcm._mantissa && (dcm._mantissa.length == 1) && (dcm._mantissa[0] == 1))
317 function _CPDecimalSet(t, s)
320 t._exponent = s._exponent;
321 t._isNegative = s._isNegative;
322 t._isCompact = s._isCompact;
324 t._mantissa = Array.prototype.slice.call(s._mantissa, 0);
327 function _CPDecimalSetZero(result)
329 result._mantissa = [0];
330 result._exponent = 0;
331 result._isNegative = NO;
332 result._isCompact = YES;
336 function _CPDecimalSetOne(result)
338 result._mantissa = [1];
339 result._exponent = 0;
340 result._isNegative = NO;
341 result._isCompact = YES;
352 return (dcm._isNaN)?YES:NO;
363 return {_exponent:dcm._exponent,
364 _isNegative:dcm._isNegative,
365 _isCompact:dcm._isCompact,
367 _mantissa:Array.prototype.slice.call(dcm._mantissa, 0)
381 if (leftOperand._isNaN && rightOperand._isNaN)
384 if (leftOperand._isNegative != rightOperand._isNegative)
386 if (rightOperand._isNegative)
393 var leftIsZero = (leftOperand._mantissa.length == 1 && leftOperand._mantissa[0] == 0),
394 rightIsZero = (rightOperand._mantissa.length == 1 && rightOperand._mantissa[0] == 0),
396 s1 = leftOperand._exponent + leftOperand._mantissa.length,
397 s2 = rightOperand._exponent + rightOperand._mantissa.length;
399 if (leftIsZero && rightIsZero)
402 if (leftIsZero || (s1 < s2 && !rightIsZero))
404 if (rightOperand._isNegative)
409 if (rightIsZero || (s1 > s2 && !leftIsZero))
411 if (leftOperand._isNegative)
418 var l = MIN(leftOperand._mantissa.length, rightOperand._mantissa.length),
423 var d = rightOperand._mantissa[i] - leftOperand._mantissa[i];
427 if (rightOperand._isNegative)
434 if (rightOperand._isNegative)
442 if (leftOperand._mantissa.length > rightOperand._mantissa.length)
444 if (rightOperand._isNegative)
449 if (leftOperand._mantissa.length < rightOperand._mantissa.length)
451 if (rightOperand._isNegative)
463 function _SimpleAdd(result, leftOperand, rightOperand, roundingMode, longMode)
465 var factor = (longMode)?2:1;
467 _CPDecimalSet(result, leftOperand);
469 var j = leftOperand._mantissa.length - rightOperand._mantissa.length,
470 l = rightOperand._mantissa.length,
473 error = CPCalculationNoError;
478 var d = rightOperand._mantissa[i] + result._mantissa[i + j] + carry;
487 result._mantissa[i + j] = d;
492 for (i = j - 1; i >= 0; i--)
494 if (result._mantissa[i] != 9)
496 result._mantissa[i]++;
500 result._mantissa[i] = 0;
505 Array.prototype.splice.call(result._mantissa, 0, 0, 1);
510 var scale = - result._exponent - 1;
534 function CPDecimalAdd(result, leftOperand, rightOperand, roundingMode, longMode)
536 if (leftOperand._isNaN || rightOperand._isNaN)
539 return CPCalculationNoError;
545 _CPDecimalSet(result, rightOperand);
546 return CPCalculationNoError;
551 _CPDecimalSet(result, leftOperand);
552 return CPCalculationNoError;
559 if (leftOperand._isNegative != rightOperand._isNegative)
561 if (leftOperand._isNegative)
577 ll = n1._mantissa.length,
578 lr = n2._mantissa.length;
588 if (leftOperand._isNegative)
596 adderror = _SimpleAdd(result, n1, n2, roundingMode, longMode);
600 adderror = _SimpleAdd(result, n2, n1, roundingMode, longMode);
603 result._isNegative = YES;
615 adderror = _SimpleAdd(result, n2, n1, roundingMode, longMode);
619 adderror = _SimpleAdd(result, n1, n2, roundingMode, longMode);
625 if (adderror == CPCalculationNoError)
632 function _SimpleSubtract(result, leftOperand, rightOperand, roundingMode)
634 var error = CPCalculationNoError,
636 l = rightOperand._mantissa.length,
637 j = leftOperand._mantissa.length - l,
640 _CPDecimalSet(result, leftOperand);
645 var d = result._mantissa[i + j] - rightOperand._mantissa[i] - borrow;
655 result._mantissa[i + j] = d;
660 for (i = j - 1; i >= 0; i--)
662 if (result._mantissa[i] != 0)
664 result._mantissa[i]--;
667 result._mantissa[i] = 9;
690 if (leftOperand._isNaN || rightOperand._isNaN)
693 return CPCalculationNoError;
699 _CPDecimalSet(result, rightOperand);
700 result._isNegative = !result._isNegative;
701 return CPCalculationNoError;
706 _CPDecimalSet(result, leftOperand);
707 return CPCalculationNoError;
712 error1 = CPCalculationNoError;
715 if (leftOperand._isNegative != rightOperand._isNegative)
717 if (leftOperand._isNegative)
720 error1 =
CPDecimalAdd(result, n1, rightOperand, roundingMode);
721 result._isNegative = YES;
733 return CPDecimalAdd(result, leftOperand, n2, roundingMode);
742 _CPDecimalSetZero(result);
743 return CPCalculationNoError;
747 if (leftOperand._isNegative)
754 error1 = _SimpleSubtract(result, n1, n2, roundingMode);
755 result._isNegative = YES;
759 error1 = _SimpleSubtract(result, n2, n1, roundingMode);
766 error1 = _SimpleSubtract(result, n2, n1, roundingMode);
767 result._isNegative = YES;
771 error1 = _SimpleSubtract(result, n1, n2, roundingMode);
777 if (error1 == CPCalculationNoError)
784 function _SimpleDivide(result, leftOperand, rightOperand, roundingMode)
786 var error = CPCalculationNoError,
793 _CPDecimalSetZero(result);
797 while ((used < leftOperand._mantissa.length) || (n1._mantissa.length
798 && !((n1._mantissa.length == 1) && (n1._mantissa[0] == 0))))
808 Array.prototype.push.call(n1._mantissa, 0);
814 if (used < leftOperand._mantissa.length)
817 if (n1._mantissa.length || leftOperand._mantissa[used])
820 Array.prototype.push.call(n1._mantissa, (leftOperand._mantissa[used]));
836 Array.prototype.push.call(n1._mantissa, 0);
848 result._mantissa[k - 1] = 0;
870 if (error1 != CPCalculationNoError)
873 result._mantissa[k - 1]++;
890 var error = CPCalculationNoError,
891 exp = leftOperand._exponent - rightOperand._exponent,
892 neg = (leftOperand._isNegative != rightOperand._isNegative);
894 if (leftOperand._isNaN || rightOperand._isNaN)
897 return CPCalculationNoError;
909 _CPDecimalSetZero(result);
910 return CPCalculationNoError;
923 error = _SimpleDivide(result, n1, n2, roundingMode);
942 CPDecimalSetZero(result);
947 result._exponent += exp;
948 result._isNegative = neg;
953 function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerMode)
955 var error = CPCalculationNoError,
960 _CPDecimalSetZero(result);
963 for (var i = 0; i < rightOperand._mantissa.length; i++)
965 _CPDecimalSetZero(n);
967 n._exponent = rightOperand._mantissa.length - i - 1;
969 d = rightOperand._mantissa[i];
974 for (var j = leftOperand._mantissa.length - 1; j >= 0; j--)
976 e = leftOperand._mantissa[j] * d + carry;
980 carry = FLOOR(e / 10);
987 n._mantissa[j + 1] = e;
990 n._mantissa[0] = carry;
994 error1 =
CPDecimalAdd(result, result, n, roundingMode, YES);
996 if (error1 != CPCalculationNoError)
1003 result._isNaN = YES;
1007 result._exponent += exp;
1012 result._isCompact = NO;
1034 var error = CPCalculationNoError,
1035 exp = leftOperand._exponent + rightOperand._exponent,
1036 neg = (leftOperand._isNegative != rightOperand._isNegative);
1038 if (leftOperand._isNaN || rightOperand._isNaN)
1040 result._isNaN = YES;
1041 return CPCalculationNoError;
1047 _CPDecimalSetZero(result);
1048 return CPCalculationNoError;
1055 result._isNaN = YES;
1068 n1._isNegative = NO;
1069 n2._isNegative = NO;
1073 ll = n1._mantissa.length,
1074 lr = n2._mantissa.length;
1085 error = _SimpleMultiply(result, n1, n2, roundingMode, powerMode);
1089 error = _SimpleMultiply(result, n2, n1, roundingMode, powerMode);
1096 result._isNaN = YES;
1111 _CPDecimalSetZero(result);
1116 result._exponent += exp;
1117 result._isNegative = neg;
1133 _CPDecimalSet(result, dcm);
1135 var p = result._exponent + power;
1139 result._isNaN = YES;
1145 result._isNaN = YES;
1149 result._exponent += power;
1150 return CPCalculationNoError;
1164 var error = CPCalculationNoError,
1165 neg = (dcm._isNegative && (power % 2)),
1168 n1._isNegative = NO;
1170 _CPDecimalSetOne(result);
1189 result._isNegative = neg;
1217 var factor = (longMode) ? 2 : 1;
1219 if (dcm1._isNaN || dcm2._isNaN)
1220 return CPCalculationNoError;
1223 if (!dcm1._isCompact)
1226 if (!dcm2._isCompact)
1229 if (dcm1._exponent == dcm2._exponent)
1230 return CPCalculationNoError;
1232 var e1 = dcm1._exponent,
1233 e2 = dcm2._exponent;
1236 var l2 = dcm2._mantissa.length,
1237 l1 = dcm1._mantissa.length,
1242 if (e2 > e1 && e1 >= 0 && e2 >= 0)
1244 else if (e2 > e1 && e1 < 0 && e2 >= 0)
1246 else if (e2 > e1 && e1 < 0 && e2 < 0)
1248 else if (e2 < e1 && e1 >= 0 && e2 >= 0)
1250 else if (e2 < e1 && e1 >= 0 && e2 < 0)
1252 else if (e2 < e1 && e1 < 0 && e2 < 0)
1260 for (var i = 0; i < l; i++)
1263 Array.prototype.push.call(dcm2._mantissa, 0);
1265 Array.prototype.push.call(dcm1._mantissa, 0);
1270 dcm2._exponent -= l;
1271 dcm2._isCompact = NO;
1275 dcm1._exponent -= l;
1276 dcm1._isCompact = NO;
1280 if (l != ABS(e2 - e1))
1296 if ((dcm1._exponent != dcm2._exponent) && ((!l1) || (!l2)))
1301 l1 = dcm1._mantissa.length;
1303 for (var i = 0; i < l; i++)
1305 dcm1._mantissa[i + l1] = 0;
1307 dcm1._isCompact = NO;
1308 dcm1._exponent = dcm2._exponent;
1312 l2 = dcm2._mantissa.length;
1314 for (var i = 0; i < l; i++)
1316 dcm2._mantissa[i + l2] = 0;
1318 dcm2._exponent = dcm1._exponent;
1319 dcm2._isCompact = NO;
1326 return CPCalculationNoError;
1343 _CPDecimalSet(result, dcm);
1348 if (!dcm._isCompact)
1357 var mc = result._mantissa.length,
1358 l = mc + scale + result._exponent;
1365 _CPDecimalSetZero(result);
1375 result._exponent += mc - l;
1377 switch (roundingMode)
1380 up = result._isNegative;
1384 up = !result._isNegative;
1388 n = result._mantissa[l];
1392 case _CPRoundHalfDown:
1393 n = result._mantissa[l];
1398 n = result._mantissa[l];
1409 c = result._mantissa[l - 1];
1410 up = ((c % 2) != 0);
1420 result._mantissa = Array.prototype.slice.call(result._mantissa, 0, l);
1424 for (var i = l-1; i >= 0; i--)
1426 if (result._mantissa[i] != 9)
1428 result._mantissa[i]++;
1432 result._mantissa[i] = 0;
1439 result._mantissa[0] = 1;
1446 Array.prototype.push.call(result._mantissa, 0);
1471 _CPDecimalSetZero(dcm);
1477 while (dcm._mantissa[0] === 0)
1478 Array.prototype.shift.call(dcm._mantissa);
1481 while (dcm._mantissa[dcm._mantissa.length - 1] === 0)
1483 Array.prototype.pop.call(dcm._mantissa);
1494 dcm._isCompact = YES;
1514 if (dcm._isNegative)
1517 var k = dcm._mantissa.length,
1518 l = ((dcm._exponent < 0) ? dcm._exponent : 0) + k;
1524 for (i = 0; i < ABS(l); i++)
1535 for (i = 0; i < l; i++)
1537 string += dcm._mantissa[i];
1543 for (i = l; i < k; i++)
1545 string += dcm._mantissa[i];
1549 for (i = 0; i < dcm._exponent; i++)