68 int carry, ResultChar;
82 ResultChar = carry + *AccumPtr + (MultChar * *top--);
85 carry = ResultChar / 10;
86 ResultChar -= carry * 10;
92 *AccumPtr-- = ResultChar;
97 *AccumPtr-- = (char)carry;
108 char *ResultPtr, *AccumPtr, *Current, *OutPtr;
112 size_t NumberDigits, TotalDigits, ExtraDigit;
121 if (left->
sign == 0 || right->
sign == 0)
137 TotalDigits = ((NumberDigits+1) * 2) + 1;
146 OutPtr = resultBufFast;
148 memset(OutPtr,
'\0',TotalDigits);
154 ResultPtr = AccumPtr + TotalDigits - 1;
159 for (i = SmallNum->
length ; i ; i-- )
174 AccumLen = (++ResultPtr - AccumPtr) + SmallNum->
length;
180 if (AccumLen > NumberDigits)
183 ExtraDigit = AccumLen -(NumberDigits + 1);
184 AccumLen = NumberDigits + 1;
194 result->
exp = LargeNum->
exp + SmallNum->
exp + ExtraDigit;
197 result->
length = AccumLen;
205 char *data2,
size_t length2,
206 char *result,
int Mult)
232 data1 += (length1 -1);
233 data2 += (length2 -1);
237 extra = length1 - length2;
243 DivChar = carry + *data1-- - (*data2-- * Mult);
247 carry = (DivChar/10) -10;
254 *--OutPtr = (char)DivChar;
263 *--OutPtr = (char)*data1--;
270 DivChar = carry + *data1--;
275 *--OutPtr = (char)DivChar;
279 *--OutPtr = (char)DivChar;
282 *--OutPtr = *data1--;
308 char *resultPtr, *Output, *rightPtr, *leftPtr, *SaveLeftPtr, *SaveRightPtr;
313 size_t NumberDigits, totalDigits, resultDigits;
334 else if (!this->
sign)
348 CalcExp = left->
exp - right->
exp;
368 totalDigits = ((NumberDigits + 1) * 2) + 1;
381 leftPtr = leftBufFast;
382 rightPtr = rightBufFast;
389 memset(leftPtr + left->
length,
'\0', totalDigits - left->
length);
392 memset(rightPtr + right->
length,
'\0', totalDigits - right->
length);
400 SaveLeftPtr = leftPtr;
401 SaveRightPtr = rightPtr;
421 SaveLeft->
exp = NumberDigits * 2 - SaveLeft->
length + 1;
422 SaveRight->
exp = rightPadding;
436 DivChar = *Num2 * 10;
437 if (SaveRight->
length > 1)
439 DivChar += *(Num2 + 1);
476 rc = memcmp(Num1, Num2, SaveLeft->
length);
487 *resultPtr++ = (char)(thisDigit + 1);
489 goto PowerDivideDone;
503 multiplier = *Num1 * 10 + *(Num1 + 1);
514 multiplier = multiplier * 10 / DivChar;
526 thisDigit += multiplier;
533 while (*Num1 == 0 && SaveLeft->
length > 1)
541 if (resultDigits || thisDigit)
543 *resultPtr++ = (char) thisDigit;
549 if (*Num1 ==
'\0' || resultDigits > NumberDigits)
564 if (SaveLeft->
length == 1 && *Num1 ==
'\0')
574 if (rightPadding > 0)
591 ( resultDigits + CalcExp) > NumberDigits) ||
592 (CalcExp < 0 && (size_t)
Numerics::abs(CalcExp) > resultDigits)))
614 SaveLeftPtr += left->
length;
616 SaveRightPtr = resultPtr + SaveLeft->
length + adjustNum1;
618 Accum->
exp = left->
exp - (SaveRightPtr - SaveLeftPtr);
633 result = this->
clone();
634 result->setupNumber();
645 Accum->
length = resultDigits;
646 Accum->
exp = CalcExp;
647 if (Accum->
length > NumberDigits)
651 Accum->
exp += (Accum->
length - NumberDigits);
652 Accum->
length = NumberDigits;
657 Num1 = resultPtr + Accum->
length - 1;
658 while (!*Num1 && Accum->
length)
675 result->exp = Accum->
exp;
676 result->sign = Accum->
sign;
678 result->adjustPrecision(resultPtr, NumberDigits);
690 char *Accum, *AccumPtr, *OutPtr, *TempPtr;
698 NegativePower =
false;
707 bool alternativeResult = PowerObj->
messageSend(OREF_POWER_RIGHT, args, 1, 0, result,
false);
714 NegativePower =
true;
715 powerValue = -powerValue;
731 else if (powerValue == 0)
770 for (extra=0, OldNorm = powerValue; OldNorm ;extra++ )
774 NumberDigits += (extra + 1);
778 AccumLen = (2 * (NumberDigits+1)) + 1;
788 memcpy(AccumPtr, left->number, left->length);
795 while (!((
size_t)powerValue &
HIBIT))
807 if ((
size_t) powerValue &
HIBIT)
818 AccumPtr = AccumObj->adjustNumber(AccumPtr, Accum, AccumLen, NumberDigits);
825 AccumPtr =
multiplyPower(AccumPtr, AccumObj, AccumPtr, AccumObj, OutPtr, AccumLen, NumberDigits);
830 AccumPtr = AccumObj->adjustNumber(AccumPtr, Accum, AccumLen, NumberDigits);
838 AccumPtr =
dividePower(AccumPtr, AccumObj, Accum, NumberDigits);
841 NumberDigits -= (extra + 1);
843 AccumPtr = AccumObj->stripLeadingZeros(AccumPtr);
846 if (AccumObj->length > NumberDigits)
850 AccumObj->exp += (AccumObj->length - NumberDigits);
851 AccumObj->length = NumberDigits;
852 AccumObj->mathRound(AccumPtr);
856 TempPtr = AccumPtr + AccumObj->length -1;
858 while (!*TempPtr && AccumObj->length)
869 result->
sign = AccumObj->sign;
870 result->
exp = AccumObj->exp;
871 result->
length = AccumObj->length;
885 char *OutPtr,
size_t OutLen,
size_t NumberDigits)
890 char *current, *resultPtr;
891 char *AccumPtr = NULL;
898 memset(OutPtr,
'\0', OutLen);
901 resultPtr = OutPtr + OutLen - 1;
904 current = rightPtr + right->
length;
906 for (i = right->
length ; i ; i-- )
919 AccumLen = (size_t)(++resultPtr - AccumPtr) + right->
length;
925 if (AccumLen > NumberDigits)
927 ExtraDigit = AccumLen - NumberDigits;
935 left->
exp += (right->
exp + ExtraDigit);
951 char *resultPtr, *leftPtr, *result;
953 int DivChar, thisDigit;
965 totalDigits = ((NumberDigits + 1) * 2) + 1;
981 memset(leftPtr + 1,
'\0', totalDigits - 1);
997 DivChar = *Num2 * 10;
999 DivChar += *(Num2 + 1);
1036 rc = memcmp(Num1, Num2, left->
length);
1045 *resultPtr++ = (char)(thisDigit + 1);
1047 goto PowerDivideDone;
1059 multiplier = *Num1 * 10 + *(Num1 + 1);
1067 multiplier = multiplier * 10 / DivChar;
1068 if (multiplier == 0)
1073 thisDigit += multiplier;
1080 if (resultDigits || thisDigit)
1082 *resultPtr++ = (char) thisDigit;
1087 if (*Num1 ==
'\0' || resultDigits > NumberDigits)
1094 if (left->
length == 1 && *Num1 ==
'\0')
1104 Num1 = (
char *)memmove(leftPtr, Num1, left->
length);
1107 memset(Num1 + left->
length,
'\0', totalDigits - left->
length);
1113 Accum->
length = resultDigits;
1114 Accum->
exp = CalcExp;
1115 memcpy(Output, result, resultDigits);
void reportException(wholenumber_t error)
RexxNumberString * new_numberstring(const char *s, stringsize_t l)
void requiredArgument(RexxObject *object, RexxString *kind, size_t position)
#define Error_Overflow_overflow
#define Error_Overflow_power
#define Error_Invalid_whole_number_power
#define Error_Invalid_whole_number_rem
#define Error_Invalid_whole_number_intdiv
#define Error_Overflow_zero
static wholenumber_t abs(wholenumber_t n)
static const wholenumber_t MAX_EXPONENT
char * stripLeadingZeros(char *)
RexxNumberString * checkNumber(size_t digits)
static char * dividePower(char *AccumPtr, RexxNumberStringBase *Accum, char *Output, size_t NumberDigits)
static char * addMultiplier(char *, size_t, char *, int)
void adjustPrecision(char *, size_t)
RexxNumberString * Division(RexxNumberString *, unsigned int)
static char * multiplyPower(char *leftPtr, RexxNumberStringBase *left, char *rightPtr, RexxNumberStringBase *right, char *OutPtr, size_t OutLen, size_t NumberDigits)
RexxNumberString * clone()
RexxNumberString * Multiply(RexxNumberString *)
RexxNumberString * power(RexxObject *)
static char * subtractDivisor(char *data1, size_t length1, char *data2, size_t length2, char *result, int Mult)
RexxNumberString * prepareOperatorNumber(size_t, size_t, bool)
static size_t highBits(size_t)
bool messageSend(RexxString *, RexxObject **, size_t, size_t, ProtectedObject &, bool processUnknown=true, bool dynamicTarget=true)
virtual bool numberValue(wholenumber_t &result, size_t precision)