mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-09 04:07:12 +00:00
Use native javascript array for mantissa for big performance increase
This commit is contained in:
+62
-60
@@ -146,20 +146,20 @@ function CPDecimalMakeWithString(string, locale)
|
||||
return CPDecimalMakeNaN();
|
||||
|
||||
// Representation internally starts at most significant digit
|
||||
var m = [CPMutableArray array],
|
||||
var m = [],
|
||||
i = 0;
|
||||
for (; i < (intpart?intpart.length:0); i++)
|
||||
{
|
||||
if (i >= CPDecimalMaxDigits)
|
||||
break; // truncate
|
||||
[m addObject:parseInt(intpart.charAt(i))];
|
||||
Array.prototype.push.call(m, parseInt(intpart.charAt(i)));
|
||||
}
|
||||
var j = 0;
|
||||
for (; j < (decpart?decpart.length:0); j++)
|
||||
{
|
||||
if ((i + j) >= CPDecimalMaxDigits)
|
||||
break; // truncate
|
||||
[m addObject:parseInt(decpart.charAt(j))];
|
||||
Array.prototype.push.call(m, parseInt(decpart.charAt(j)));
|
||||
}
|
||||
|
||||
var dcm = {_exponent:exponent, _isNegative:isNegative, _isCompact:NO, _isNaN:NO, _mantissa:m};
|
||||
@@ -177,7 +177,7 @@ function CPDecimalMakeWithString(string, locale)
|
||||
*/
|
||||
function CPDecimalMakeWithParts(mantissa, exponent)
|
||||
{
|
||||
var m = [CPMutableArray array],
|
||||
var m = [],
|
||||
isNegative = NO;
|
||||
|
||||
if (mantissa < 0 )
|
||||
@@ -187,15 +187,15 @@ function CPDecimalMakeWithParts(mantissa, exponent)
|
||||
}
|
||||
|
||||
if (mantissa == 0)
|
||||
[m addObject: 0];
|
||||
Array.prototype.push.call(m, 0);
|
||||
|
||||
if (exponent > CPDecimalMaxExponent || exponent < CPDecimalMinExponent)
|
||||
return CPDecimalMakeNaN();
|
||||
|
||||
// remaining digits are disposed of via truncation
|
||||
while ((mantissa > 0) && ([m count] < CPDecimalMaxDigits)) // count selector here could be optimised away
|
||||
while ((mantissa > 0) && (m.length < CPDecimalMaxDigits)) // count selector here could be optimised away
|
||||
{
|
||||
[m insertObject:parseInt(mantissa % 10) atIndex:0];
|
||||
Array.prototype.unshift.call(m, parseInt(mantissa % 10));
|
||||
mantissa = FLOOR(mantissa / 10);
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ function CPDecimalIsOne(dcm)
|
||||
// exponent doesnt matter as long as mantissa = 0
|
||||
if (!dcm._isNaN)
|
||||
{
|
||||
if (dcm._mantissa && ([dcm._mantissa count] == 1) && (dcm._mantissa[0] == 1))
|
||||
if (dcm._mantissa && (dcm._mantissa.length == 1) && (dcm._mantissa[0] == 1))
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
@@ -305,12 +305,12 @@ function _CPDecimalSet(t,s)
|
||||
t._isNegative = s._isNegative;
|
||||
t._isCompact = s._isCompact;
|
||||
t._isNaN = s._isNaN;
|
||||
t._mantissa = [s._mantissa copy];
|
||||
t._mantissa = Array.prototype.slice.call(s._mantissa, 0);
|
||||
}
|
||||
|
||||
function _CPDecimalSetZero(result)
|
||||
{
|
||||
result._mantissa = [CPMutableArray arrayWithObject:0];
|
||||
result._mantissa = [0];
|
||||
result._exponent = 0;
|
||||
result._isNegative = NO;
|
||||
result._isCompact = YES;
|
||||
@@ -319,7 +319,7 @@ function _CPDecimalSetZero(result)
|
||||
|
||||
function _CPDecimalSetOne(result)
|
||||
{
|
||||
result._mantissa = [CPMutableArray arrayWithObject:1];
|
||||
result._mantissa = [1];
|
||||
result._exponent = 0;
|
||||
result._isNegative = NO;
|
||||
result._isCompact = YES;
|
||||
@@ -348,7 +348,7 @@ function CPDecimalCopy(dcm)
|
||||
_isNegative:dcm._isNegative,
|
||||
_isCompact:dcm._isCompact,
|
||||
_isNaN:dcm._isNaN,
|
||||
_mantissa:[dcm._mantissa copy]
|
||||
_mantissa:Array.prototype.slice.call(dcm._mantissa, 0)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -373,8 +373,8 @@ function CPDecimalCompare(leftOperand, rightOperand)
|
||||
return CPOrderedAscending;
|
||||
}
|
||||
|
||||
var s1 = leftOperand._exponent + [leftOperand._mantissa count],
|
||||
s2 = rightOperand._exponent + [rightOperand._mantissa count];
|
||||
var s1 = leftOperand._exponent + leftOperand._mantissa.length,
|
||||
s2 = rightOperand._exponent + rightOperand._mantissa.length;
|
||||
|
||||
// Sign is the same, quick check size (length + exp)
|
||||
if (s1 < s2)
|
||||
@@ -393,7 +393,7 @@ function CPDecimalCompare(leftOperand, rightOperand)
|
||||
}
|
||||
|
||||
// Same size, so check mantissa
|
||||
var l = MIN([leftOperand._mantissa count], [rightOperand._mantissa count]),
|
||||
var l = MIN(leftOperand._mantissa.length, rightOperand._mantissa.length),
|
||||
i = 0;
|
||||
|
||||
for (; i < l; i++)
|
||||
@@ -417,14 +417,14 @@ function CPDecimalCompare(leftOperand, rightOperand)
|
||||
}
|
||||
|
||||
// Same digits, check length
|
||||
if ([leftOperand._mantissa count] > [rightOperand._mantissa count])
|
||||
if (leftOperand._mantissa.length > rightOperand._mantissa.length)
|
||||
{
|
||||
if (rightOperand._isNegative)
|
||||
return CPOrderedAscending;
|
||||
else
|
||||
return CPOrderedDescending;
|
||||
}
|
||||
if ([leftOperand._mantissa count] < [rightOperand._mantissa count])
|
||||
if (leftOperand._mantissa.length < rightOperand._mantissa.length)
|
||||
{
|
||||
if (rightOperand._isNegative)
|
||||
return CPOrderedDescending;
|
||||
@@ -444,8 +444,8 @@ function _SimpleAdd(result, leftOperand, rightOperand, roundingMode, longMode)
|
||||
|
||||
_CPDecimalSet(result, leftOperand);
|
||||
|
||||
var j = [leftOperand._mantissa count] - [rightOperand._mantissa count],
|
||||
l = [rightOperand._mantissa count],
|
||||
var j = leftOperand._mantissa.length - rightOperand._mantissa.length,
|
||||
l = rightOperand._mantissa.length,
|
||||
i = l - 1,
|
||||
carry = 0,
|
||||
error = CPCalculationNoError;
|
||||
@@ -467,7 +467,7 @@ function _SimpleAdd(result, leftOperand, rightOperand, roundingMode, longMode)
|
||||
|
||||
if (carry)
|
||||
{
|
||||
for (i = j-1; i >= 0; i--)
|
||||
for (i = j - 1; i >= 0; i--)
|
||||
{
|
||||
if (result._mantissa[i] != 9)
|
||||
{
|
||||
@@ -480,13 +480,13 @@ function _SimpleAdd(result, leftOperand, rightOperand, roundingMode, longMode)
|
||||
|
||||
if (carry)
|
||||
{
|
||||
[result._mantissa insertObject:1 atIndex:0];
|
||||
Array.prototype.splice.call(result._mantissa, 0, 0, 1);
|
||||
|
||||
// The number must be shifted to the right
|
||||
if ((CPDecimalMaxDigits * factor) == [leftOperand._mantissa count])
|
||||
if ((CPDecimalMaxDigits * factor) == leftOperand._mantissa.length)
|
||||
{
|
||||
var scale = - result._exponent - 1;
|
||||
CPDecimalRound(result, result,scale,roundingMode);
|
||||
CPDecimalRound(result, result, scale, roundingMode);
|
||||
}
|
||||
|
||||
if (CPDecimalMaxExponent < result._exponent)
|
||||
@@ -550,8 +550,8 @@ function CPDecimalAdd(result, leftOperand, rightOperand, roundingMode, longMode)
|
||||
|
||||
// below is equiv of simple compare
|
||||
var comp = 0,
|
||||
ll = [n1._mantissa count],
|
||||
lr = [n2._mantissa count];
|
||||
ll = n1._mantissa.length,
|
||||
lr = n2._mantissa.length;
|
||||
if (ll == lr)
|
||||
comp = CPOrderedSame;
|
||||
else if (ll > lr)
|
||||
@@ -605,8 +605,8 @@ function _SimpleSubtract(result, leftOperand, rightOperand, roundingMode)
|
||||
{
|
||||
var error = CPCalculationNoError,
|
||||
borrow = 0,
|
||||
l = [rightOperand._mantissa count],
|
||||
j = [leftOperand._mantissa count] - l,
|
||||
l = rightOperand._mantissa.length,
|
||||
j = leftOperand._mantissa.length - l,
|
||||
i = l - 1;
|
||||
|
||||
_CPDecimalSet(result, leftOperand);
|
||||
@@ -628,7 +628,7 @@ function _SimpleSubtract(result, leftOperand, rightOperand, roundingMode)
|
||||
|
||||
if (borrow)
|
||||
{
|
||||
for (i = j-1; i >= 0; i--)
|
||||
for (i = j - 1; i >= 0; i--)
|
||||
{
|
||||
if (result._mantissa[i] != 0)
|
||||
{
|
||||
@@ -759,10 +759,10 @@ function _SimpleDivide(result, leftOperand, rightOperand, roundingMode)
|
||||
|
||||
_CPDecimalSetZero(result);
|
||||
|
||||
n1._mantissa = [CPMutableArray array];
|
||||
n1._mantissa = [];
|
||||
|
||||
while ((k < [leftOperand._mantissa count]) || ([n1._mantissa count]
|
||||
&& !(([n1._mantissa count] == 1) && (n1._mantissa[0] == 0))))
|
||||
while ((k < leftOperand._mantissa.length) || (n1._mantissa.length
|
||||
&& !((n1._mantissa.length == 1) && (n1._mantissa[0] == 0))))
|
||||
{
|
||||
while (CPOrderedAscending == CPDecimalCompare(n1, rightOperand))
|
||||
{
|
||||
@@ -771,19 +771,19 @@ function _SimpleDivide(result, leftOperand, rightOperand, roundingMode)
|
||||
if (n1._exponent)
|
||||
{
|
||||
// Put back zeros removed by compacting
|
||||
[n1._mantissa addObject:0];
|
||||
Array.prototype.push.call(n1._mantissa, 0);
|
||||
n1._exponent--;
|
||||
n1._isCompact = NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (used < [leftOperand._mantissa count])
|
||||
if (used < leftOperand._mantissa.length)
|
||||
{
|
||||
// Fill up with own digits
|
||||
if ([n1._mantissa count] || leftOperand._mantissa[used])
|
||||
if (n1._mantissa.length || leftOperand._mantissa[used])
|
||||
{
|
||||
// only add 0 if there is already something
|
||||
[n1._mantissa addObject:(leftOperand._mantissa[used])];
|
||||
Array.prototype.push.call(n1._mantissa, (leftOperand._mantissa[used]));
|
||||
n1._isCompact = NO;
|
||||
}
|
||||
used++;
|
||||
@@ -797,7 +797,7 @@ function _SimpleDivide(result, leftOperand, rightOperand, roundingMode)
|
||||
break;
|
||||
}
|
||||
// Borrow one digit
|
||||
[n1._mantissa addObject:0];
|
||||
Array.prototype.push.call(n1._mantissa, 0);
|
||||
result._exponent--;
|
||||
}
|
||||
|
||||
@@ -922,11 +922,11 @@ function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerM
|
||||
|
||||
// Do every digit of the second number
|
||||
var i = 0;
|
||||
for (; i < [rightOperand._mantissa count]; i++)
|
||||
for (; i < rightOperand._mantissa.length; i++)
|
||||
{
|
||||
_CPDecimalSetZero(n);
|
||||
|
||||
n._exponent = [rightOperand._mantissa count] - i - 1;
|
||||
n._exponent = rightOperand._mantissa.length - i - 1;
|
||||
carry = 0;
|
||||
d = rightOperand._mantissa[i];
|
||||
|
||||
@@ -934,7 +934,7 @@ function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerM
|
||||
continue;
|
||||
|
||||
var j = 0;
|
||||
for (j = [leftOperand._mantissa count]-1; j >= 0; j--)
|
||||
for (j = leftOperand._mantissa.length - 1; j >= 0; j--)
|
||||
{
|
||||
e = leftOperand._mantissa[j] * d + carry;
|
||||
if (e >= 10)
|
||||
@@ -967,11 +967,11 @@ function _SimpleMultiply(result, leftOperand, rightOperand, roundingMode, powerM
|
||||
result._exponent += exp;
|
||||
|
||||
// perform round to CPDecimalMaxDigits
|
||||
if ([result._mantissa count] > CPDecimalMaxDigits && !powerMode)
|
||||
if (result._mantissa.length > CPDecimalMaxDigits && !powerMode)
|
||||
{
|
||||
result._isCompact = NO;
|
||||
var scale = CPDecimalMaxDigits - ([result._mantissa count] + result._exponent);
|
||||
CPDecimalRound(result, result, scale ,roundingMode); // calls compact
|
||||
var scale = CPDecimalMaxDigits - (result._mantissa.length + result._exponent);
|
||||
CPDecimalRound(result, result, scale, roundingMode); // calls compact
|
||||
|
||||
error = CPCalculationLossOfPrecision;
|
||||
}
|
||||
@@ -1027,8 +1027,8 @@ function CPDecimalMultiply(result, leftOperand, rightOperand, roundingMode, powe
|
||||
|
||||
// below is equiv of simple compare
|
||||
var comp = 0,
|
||||
ll = [n1._mantissa count],
|
||||
lr = [n2._mantissa count];
|
||||
ll = n1._mantissa.length,
|
||||
lr = n2._mantissa.length;
|
||||
if (ll == lr)
|
||||
comp = CPOrderedSame;
|
||||
else if (ll > lr)
|
||||
@@ -1183,8 +1183,8 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
|
||||
e2 = dcm2._exponent;
|
||||
|
||||
// Add zeros
|
||||
var l2 = [dcm2._mantissa count],
|
||||
l1 = [dcm1._mantissa count],
|
||||
var l2 = dcm2._mantissa.length,
|
||||
l1 = dcm1._mantissa.length,
|
||||
l = 0;
|
||||
|
||||
var e = 0;
|
||||
@@ -1202,16 +1202,16 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
|
||||
e = e1 - e2;
|
||||
|
||||
if (e2 > e1)
|
||||
l = MIN((CPDecimalMaxDigits*factor) - l2, e); //(e2 - e1));
|
||||
l = MIN((CPDecimalMaxDigits * factor) - l2, e); //(e2 - e1));
|
||||
else
|
||||
l = MIN((CPDecimalMaxDigits*factor) - l1, e); //(e1 - e2));
|
||||
l = MIN((CPDecimalMaxDigits * factor) - l1, e); //(e1 - e2));
|
||||
|
||||
for (var i = 0; i < l; i++)
|
||||
{
|
||||
if (e2 > e1)
|
||||
[dcm2._mantissa addObject:0]; //dcm2._mantissa[i + l2] = 0;
|
||||
Array.prototype.push.call(dcm2._mantissa, 0); //dcm2._mantissa[i + l2] = 0;
|
||||
else
|
||||
[dcm1._mantissa addObject:0];
|
||||
Array.prototype.push.call(dcm1._mantissa, 0);
|
||||
}
|
||||
if (e2 > e1)
|
||||
{
|
||||
@@ -1246,7 +1246,7 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
|
||||
// Some zeros where cut of again by compacting
|
||||
if (e2 > e1)
|
||||
{
|
||||
l1 = [dcm1._mantissa count];
|
||||
l1 = dcm1._mantissa.length;
|
||||
l = MIN((CPDecimalMaxDigits * factor) - l1, ABS(dcm1._exponent - dcm2._exponent));
|
||||
for (var i = 0; i < l; i++)
|
||||
{
|
||||
@@ -1257,7 +1257,7 @@ function CPDecimalNormalize(dcm1, dcm2, roundingMode, longMode)
|
||||
}
|
||||
else
|
||||
{
|
||||
l2 = [dcm2._mantissa count];
|
||||
l2 = dcm2._mantissa.length;
|
||||
l = MIN((CPDecimalMaxDigits * factor) - l2, ABS(dcm2._exponent - dcm1._exponent));
|
||||
for (var i = 0; i < l; i++)
|
||||
{
|
||||
@@ -1301,7 +1301,7 @@ function CPDecimalRound(result, dcm, scale ,roundingMode)
|
||||
|
||||
_CPDecimalSet(result,dcm);
|
||||
|
||||
var mc = [result._mantissa count],
|
||||
var mc = result._mantissa.length,
|
||||
l = mc + scale + result._exponent;
|
||||
|
||||
if (mc <= l)
|
||||
@@ -1350,7 +1350,7 @@ function CPDecimalRound(result, dcm, scale ,roundingMode)
|
||||
break;
|
||||
}
|
||||
// cut mantissa
|
||||
result._mantissa = [result._mantissa subarrayWithRange:CPMakeRange(0, l)];
|
||||
result._mantissa = Array.prototype.slice.call(result._mantissa, 0, l);
|
||||
|
||||
if (up)
|
||||
{
|
||||
@@ -1373,7 +1373,7 @@ function CPDecimalRound(result, dcm, scale ,roundingMode)
|
||||
// Overflow in rounding.
|
||||
// Add one zero add the end. There must be space as
|
||||
// we just cut off some digits.
|
||||
[result._mantissa addObject:0];
|
||||
Array.prototype.push.call(result._mantissa, 0);
|
||||
}
|
||||
else
|
||||
result._exponent++;
|
||||
@@ -1392,7 +1392,7 @@ function CPDecimalRound(result, dcm, scale ,roundingMode)
|
||||
function CPDecimalCompact(dcm)
|
||||
{
|
||||
// if positive or zero exp leading zeros simply delete, trailing ones u need to increment exponent
|
||||
if (!dcm || [dcm._mantissa count] == 0 || CPDecimalIsNotANumber(dcm) )
|
||||
if (!dcm || dcm._mantissa.length == 0 || CPDecimalIsNotANumber(dcm) )
|
||||
return;
|
||||
|
||||
|
||||
@@ -1406,12 +1406,12 @@ function CPDecimalCompact(dcm)
|
||||
// if exp is zero does it make sense to have them? dont think so so delete them
|
||||
while (dcm._mantissa[0] === 0)
|
||||
{
|
||||
[dcm._mantissa removeObjectAtIndex:0];
|
||||
Array.prototype.shift.call(dcm._mantissa);
|
||||
}
|
||||
// trailing zeros, strip them
|
||||
while ([dcm._mantissa lastObject] === 0)
|
||||
while (dcm._mantissa[dcm._mantissa.length - 1] === 0)
|
||||
{
|
||||
[dcm._mantissa removeLastObject];
|
||||
Array.prototype.pop.call(dcm._mantissa);
|
||||
dcm._exponent++;
|
||||
if (dcm._exponent + 1 > CPDecimalMaxExponent)
|
||||
{
|
||||
@@ -1443,8 +1443,10 @@ function CPDecimalString(dcm, locale)
|
||||
|
||||
if (dcm._isNegative)
|
||||
string += "-";
|
||||
var k = [dcm._mantissa count],
|
||||
|
||||
var k = dcm._mantissa.length,
|
||||
l = ((dcm._exponent < 0) ? dcm._exponent : 0) + k;
|
||||
|
||||
if (l < 0)
|
||||
{
|
||||
// add leading zeros
|
||||
|
||||
Reference in New Issue
Block a user