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++)
function CPDecimalMakeZero()
function CPDecimalMakeOne()
function CPDecimalIsNotANumber(dcm)
function CPDecimalRound(result, dcm, scale, roundingMode)
function CPDecimalMultiply(result, leftOperand, rightOperand, roundingMode, powerMode)
function CPDecimalMakeWithString(string, locale)
function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
CPDecimalNumberUnderflowException
function CPDecimalCompact(dcm)
function CPDecimalSubtract(result, leftOperand, rightOperand, roundingMode)
function CPDecimalIsOne(dcm)
function CPDecimalIsZero(dcm)
function CPDecimalCopy(dcm)
function CPDecimalString(dcm, locale)
function CPDecimalMultiplyByPowerOf10(result, dcm, power, roundingMode)
CPCalculationDivideByZero
function CPDecimalMakeNaN()
CPCalculationLossOfPrecision
function CPDecimalPower(result, dcm, power, roundingMode)
function CPDecimalAdd(result, leftOperand, rightOperand, roundingMode, longMode)
function CPDecimalCompare(leftOperand, rightOperand)
CPDecimalNumberExactnessException
CPRoundingMode CPRoundPlain
CPDecimal CPDecimalMaxDigits
function CPDecimalMakeWithParts(mantissa, exponent)
function CPDecimalDivide(result, leftOperand, rightOperand, roundingMode)
CPDecimalNumberOverflowException
CPDecimalNumberDivideByZeroException