ooRexx  4.2.0-source
About: ooRexx (Open Object Rexx) is a free implementation of Object Rexx. Object Rexx is an enhancement of the classic Rexx interpreter; a full-featured programming language with a human-oriented syntax.
  Fossies Dox: ooRexx-4.2.0-source.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

NumberStringMath2.cpp
Go to the documentation of this file.
1 /*----------------------------------------------------------------------------*/
2 /* */
3 /* Copyright (c) 1995, 2004 IBM Corporation. All rights reserved. */
4 /* Copyright (c) 2005-2009 Rexx Language Association. All rights reserved. */
5 /* */
6 /* This program and the accompanying materials are made available under */
7 /* the terms of the Common Public License v1.0 which accompanies this */
8 /* distribution. A copy is also available at the following address: */
9 /* http://www.oorexx.org/license.html */
10 /* */
11 /* Redistribution and use in source and binary forms, with or */
12 /* without modification, are permitted provided that the following */
13 /* conditions are met: */
14 /* */
15 /* Redistributions of source code must retain the above copyright */
16 /* notice, this list of conditions and the following disclaimer. */
17 /* Redistributions in binary form must reproduce the above copyright */
18 /* notice, this list of conditions and the following disclaimer in */
19 /* the documentation and/or other materials provided with the distribution. */
20 /* */
21 /* Neither the name of Rexx Language Association nor the names */
22 /* of its contributors may be used to endorse or promote products */
23 /* derived from this software without specific prior written permission. */
24 /* */
25 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
26 /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
27 /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
28 /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
29 /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
30 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
31 /* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
32 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
33 /* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
34 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
35 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36 /* */
37 /*----------------------------------------------------------------------------*/
38 /******************************************************************************/
39 /* REXX Kernel okmath2.c */
40 /* */
41 /* Arithmetic function for the NumberString Class */
42 /* Multiply/Divide/Power */
43 /* */
44 /******************************************************************************/
45 #include <ctype.h>
46 #include <stdlib.h>
47 #include <string.h>
48 
49 #include "RexxCore.h"
50 #include "NumberStringClass.hpp"
51 #include "ArrayClass.hpp"
52 #include "BufferClass.hpp"
53 #include "RexxActivity.hpp"
54 #include "NumberStringMath.hpp"
55 #include "ActivityManager.hpp"
56 
58  char *top, /* data pointer of "top" number */
59  size_t topLen, /* length of the top number */
60  char *AccumPtr, /* output accumulator location */
61  int MultChar) /* multiplier value */
62 /*********************************************************************/
63 /* Function: Multiply current digit through "top" number and add */
64 /* result to the accumulator. */
65 /*********************************************************************/
66 {
67  int carry, ResultChar;
68 
69  carry = 0; /* no carry at this point. */
70  top += (topLen - 1); /* move data point to end of data. */
71 
72  /* while there are digits left to */
73  /* multiply and there is room to put */
74  /* more digits. */
75  while (topLen-- )
76  {
77  /* Multiply char by top digit and add*/
78  /* the accumvalue for position and */
79  /* and carry. and adjust pointer to */
80  /* the next digit positions. */
81  ResultChar = carry + *AccumPtr + (MultChar * *top--);
82  if (ResultChar >= 10)
83  { /* Do we have carry to worry about? */
84  carry = ResultChar / 10; /* Yes, calculate the carry over. */
85  ResultChar -= carry * 10; /* adjust number down. */
86  }
87  else
88  {
89  carry = 0; /* no carry, */
90  }
91  *AccumPtr-- = ResultChar; /* Set result char to the accum pos */
92  /* and point accum to next position. */
93  }
94  if (carry)
95  { /* still room to put a digit */
96  *AccumPtr-- = (char)carry; /* yes, put carry into next pos. */
97  }
98  return ++AccumPtr; /* return pointer to start of Accum. */
99 }
100 
102 /*********************************************************************/
103 /* Function: Multiply two NumberString objects */
104 /*********************************************************************/
105 {
106  RexxNumberString *left, *right, *result, *LargeNum, *SmallNum;
107  char *ResultPtr, *AccumPtr, *Current, *OutPtr;
108  char MultChar;
109  size_t AccumLen;
110  size_t i;
111  size_t NumberDigits, TotalDigits, ExtraDigit;
112  char resultBufFast[FASTDIGITS]; /* fast allocation if default digits */
113 
114  NumberDigits = number_digits(); /* Get the current Numeric Digits */
115 
116  /* prepare both numbers */
117  left = this->checkNumber(NumberDigits);
118  right = other->checkNumber(NumberDigits);
119  /* either number 0 to begin with? */
120  if (left->sign == 0 || right->sign == 0)
121  {
122  return new_numberstring("0", 1); /* Yes, then result is Zero. */
123  }
124 
125  if (left->length > right->length)
126  { /* Determine the large number */
127  LargeNum = left; /* left is larger, set up large and */
128  SmallNum = right; /* small for right */
129  }
130  else
131  {
132  LargeNum = right; /* right is larger, set up large and */
133  SmallNum = left; /* small for left. */
134  }
135 
136  TotalDigits = ((NumberDigits+1) * 2) + 1;
137  /* working with large numbers? */
138  if (TotalDigits > FASTDIGITS)
139  {
140  /* get a work are for result digits. */
141  OutPtr = buffer_alloc(TotalDigits);
142  }
143  else
144  {
145  OutPtr = resultBufFast; /* use the local version */
146  }
147  memset(OutPtr,'\0',TotalDigits); /* Make sure work area is zero */
148 
149  AccumPtr = OutPtr; /* Set up our acummulator */
150  AccumLen = 0; /* no data at this time. */
151  /* Set up result Pointer. Point to */
152  /* the end of the data. */
153  ResultPtr = AccumPtr + TotalDigits - 1;
154  /* Set up current digit ptr. */
155  Current = SmallNum->number + SmallNum->length;
156 
157  /* do for all multiplier digits */
158  for (i = SmallNum->length ; i ; i-- )
159  {
160  Current--; /* shift add location by 1. */
161  MultChar = *Current; /* get new multiplier digit. */
162  if (MultChar)
163  { /* is this new digit a Zero? */
164  /* nope, go do multiplication of */
165  /* digit */
166  AccumPtr = addMultiplier(LargeNum->number, LargeNum->length, ResultPtr, MultChar);
167  }
168  /* If number is zero we don't need */
169  /* to do anything. */
170  ResultPtr--; /* Backup Result Ptr, for next digit */
171  } /* go do next digit. */
172  /* Get length of computed number. */
173  AccumLen = (++ResultPtr - AccumPtr) + SmallNum->length;
174 
175  /* AccumPtr now points to result, */
176  /* the len of result is in AccumLen */
177 
178  /* now get a real Object for dat */
179  if (AccumLen > NumberDigits)
180  { /* Is result len greater then Digits */
181  /* save amount over digits for exp */
182  ExtraDigit = AccumLen -(NumberDigits + 1);
183  AccumLen = NumberDigits + 1; /* we will only use Digits + 1 */
184  }
185  else
186  {
187  ExtraDigit = 0; /* Length OK, no adjusting Exp. */
188  }
189 
190  /* go get the new object. */
191  result = (RexxNumberString *)new_numberstring(NULL, AccumLen);
192  /* get the result exponent */
193  result->exp = LargeNum->exp + SmallNum->exp + ExtraDigit;
194  /* Compute the Sign */
195  result->sign = LargeNum->sign * SmallNum->sign;
196  result->length = AccumLen; /* Set length of result. */
197  /* Make sure result is in correct */
198  /* precision */
199  result->adjustPrecision(AccumPtr, NumberDigits);
200  return result; /* return computed value. */
201 } /* All done, */
202 
203 char *RexxNumberString::subtractDivisor(char *data1, size_t length1,
204  char *data2, size_t length2,
205  char *result, int Mult)
206 /*********************************************************************/
207 /* Function: Subtraction routine for division */
208 /*********************************************************************/
209 {
210  char *OutPtr;
211  int carry, DivChar;
212  size_t extra;
213  /* This rountine actually does the divide of the Best Guess */
214  /* Mult. This Best guess is a guess at how many times the */
215  /* dividend will go into the divisor, since it is only a */
216  /* guess we make sure we guess to the low side, if low we */
217  /* always adjust our guess and recompute. */
218  /* We multiply the Dividend(Data2) by mult and then subtract*/
219  /* the result from the Divisor (Data1) and this result is */
220  /* put into RESULT. Since Mult is guaranteed to be correct*/
221  /* or low, the result is guaranteed to never be negative. */
222 
223  /* xxMxxx <- M signifies this Mult */
224  /* ______________ */
225  /* dividend ) divisor */
226  /* -iiiiiiiii <- result of M x Divisor */
227  /* =========== */
228  /* rrrrrrrrr <- result returned */
229 
230 
231  data1 += (length1 -1); /* point to end of data1 */
232  data2 += (length2 -1); /* point to end of data2 */
233 
234  OutPtr = result + 1; /* setup output pointer */
235  carry = 0; /* no carry at this point. */
236  extra = length1 - length2; /* get extra byte count. */
237 
238  while (length2--)
239  { /* do all digits in second number */
240  /* compute this div value, and bump */
241  /* data pointer to the next digit. */
242  DivChar = carry + *data1-- - (*data2-- * Mult);
243  if (DivChar < 0)
244  { /* is this div value negative? */
245  DivChar += 100; /* make it positive, by adding 100 */
246  carry = (DivChar/10) -10; /* calculate borrow out. */
247  DivChar %= 10; /* compute real result remainder */
248  }
249  else /* div value is not negative. */
250  {
251  carry = 0; /* clear out carry value. */
252  }
253  *--OutPtr = (char)DivChar; /* set this digit in output */
254  } /* go back and do next divide. */
255 
256  if (extra)
257  { /* is ther more to process? */
258  if (!carry)
259  { /* is there a carry left over? */
260  while (extra--) /* no, just copy each remaining */
261  {
262  *--OutPtr = (char)*data1--; /* digit from data1. */
263  }
264  }
265  else
266  {
267  while (extra--)
268  { /* carry left over, do for all extra */
269  DivChar = carry + *data1--; /* add carry to digit. */
270  if (DivChar < 0)
271  { /* is result negative? */
272  DivChar += 10; /* add 10(borrow) to digit value */
273  carry = -1; /* have another carry. */
274  *--OutPtr = (char)DivChar; /* put digit into result */
275  }
276  else
277  {
278  *--OutPtr = (char)DivChar; /* finished w/ carry place in result */
279  while (extra--) /* now just copy rest of digits */
280  {
281  *--OutPtr = *data1--; /* and adjust for next digit. */
282  }
283  break; /* all done, break out of loop */
284  }
285  }
286  }
287  }
288  return OutPtr; /* return pointer to start of result */
289 }
290 
291 
293 /*********************************************************************/
294 /* Function: Divide two numbers */
295 /*********************************************************************/
296 {
297  RexxNumberString *left, *right;
298  RexxNumberStringBase *Accum; /* dummy accumulator object */
299  RexxNumberStringBase *SaveLeft; /* dummy operator object */
300  RexxNumberStringBase *SaveRight; /* dummy operator object */
301  /* buffers for dummy arguments */
302  char AccumBuffer[sizeof(RexxNumberStringBase)];
303  char SaveLeftBuffer[sizeof(RexxNumberStringBase)];
304  char SaveRightBuffer[sizeof(RexxNumberStringBase)];
305  RexxNumberString *result;
306  char *Num1, *Num2;
307  char *resultPtr, *Output, *rightPtr, *leftPtr, *SaveLeftPtr, *SaveRightPtr;
308  wholenumber_t multiplier, rc;
309  wholenumber_t DivChar, thisDigit;
310  wholenumber_t CalcExp;
311 
312  size_t NumberDigits, totalDigits, resultDigits;
313  size_t adjustNum1;
314  char leftBufFast[FASTDIGITS]; /* fast allocation if default */
315  char rightBufFast[FASTDIGITS]; /* fast allocation if default */
316  char outBufFast[FASTDIGITS]; /* fast allocation if default */
317  size_t rightPadding; /* amount right side is padded by */
318 
319  SaveLeftPtr = NULL;
320 
321  /* NOTE: this routine if very similiar to the PowerDivide */
322  /* routine, these we kept as seperate routines since there*/
323  /* are enough subtile differences between the objectPointererations */
324  /* that combining them would make an already complex */
325  /* routine even more so. When fixing/updating/adding to */
326  /* this routin also check PowerDivide for similiar updates*/
327 
328  if (!other->sign)
329  { /* is the right number zero? */
330  /* yes, divide by Zero. */
332  }
333  else if (!this->sign)
334  { /* is left number Zero? */
335  /* yes, just return a zero. */
336  return(RexxNumberString *)IntegerZero;
337  }
338  /* set up address of temporaries */
339  Accum = (RexxNumberStringBase *)AccumBuffer;
340  SaveLeft = (RexxNumberStringBase *)SaveLeftBuffer;
341  SaveRight = (RexxNumberStringBase *)SaveRightBuffer;
342  NumberDigits = number_digits(); /* get current digits setting. */
343  /* make sure we've got good copy of */
344  /* our working numbers */
345  left = this->checkNumber(NumberDigits);
346  right = other->checkNumber(NumberDigits);
347  CalcExp = left->exp - right->exp; /* compute the new exponents */
348  /* calculate expected resultant exp */
349  CalcExp += (wholenumber_t)left->length - (wholenumber_t)right->length;
350  /* is exp < 0 and doing // or % */
351  if (CalcExp < 0 && DivOP != OT_DIVIDE)
352  {
353  if (DivOP == OT_INT_DIVIDE)
354  { /* Are we doing % (integer Divide)? */
355  /* yes, result is zero. */
356  return(RexxNumberString *)IntegerZero;
357  }
358  else
359  {
360  /* We are doing //, return left(this)*/
361  result = left->prepareOperatorNumber(NumberDigits + 1, NumberDigits, NOROUND);
362  result->setupNumber();
363  return result;
364  }
365  }
366 
367  totalDigits = ((NumberDigits + 1) * 2) + 1;
368  if (totalDigits > FASTDIGITS)
369  { /* working with large numbers? */
370  /* No fast path here, do Division */
371  /* get buffer for left digit data. */
372  leftPtr = buffer_alloc(totalDigits);
373  /* and right digit data */
374  rightPtr = buffer_alloc(totalDigits);
375  /* get buffer for result digit data. */
376  Output = buffer_alloc(totalDigits);
377  }
378  else
379  {
380  leftPtr = leftBufFast; /* use non-allocated version for the */
381  rightPtr = rightBufFast;
382  Output = outBufFast;
383  }
384  /* now copy the data itself into */
385  /* the temp data buffers. */
386  memcpy(leftPtr,left->number, left->length);
387  /* pad the output area with zeros. */
388  memset(leftPtr + left->length, '\0', totalDigits - left->length);
389  memcpy(rightPtr, right->number, right->length);
390  /* pad the output area with zeros. */
391  memset(rightPtr + right->length, '\0', totalDigits - right->length);
392  resultPtr = Output; /* Set up result, point to end of */
393  /* make copies of right number info */
394  memcpy(SaveRight, right, sizeof(RexxNumberStringBase));
395  /* make copies of left number info */
396  memcpy(SaveLeft, left, sizeof(RexxNumberStringBase));
397  if (DivOP == OT_REMAINDER)
398  { /* Are we doing remainder divide? */
399  SaveLeftPtr = leftPtr; /* Save initial pointers to left */
400  SaveRightPtr = rightPtr; /* and right numbers. */
401  SaveRight->sign = 1; /* force dividend sign positive. */
402  }
403  /* compute sign of result. */
404  Accum->sign = left->sign * SaveRight->sign;
405 
406  /* is right numebr longer than left? */
407  if (SaveRight->length > SaveLeft->length)
408  {
409  SaveLeft->length = SaveRight->length;/* set both numbers to same length */
410  rightPadding = 0; /* no padding needed for right number*/
411  }
412  else
413  { /* Left number is longer. */
414  /* no padding needed for right number*/
415  rightPadding = SaveLeft->length - SaveRight->length;
416  SaveRight->length = SaveLeft->length;/* set both numbers to same length */
417  }
418 
419  /* Set the new exponents of two */
420  SaveLeft->exp = NumberDigits * 2 - SaveLeft->length + 1;
421  SaveRight->exp = rightPadding; /* work numbers. */
422  adjustNum1 = 0; /* Set to 0 to start with. */
423  Num1 = leftPtr; /* Num1 is ldivisor digit pointer */
424  Num2 = rightPtr; /* Num2 is dividend digit pointer */
425 
426  /* When generate a best guess digits for result we will look*/
427  /* use the 1st 2 digits of the dividend (if there are 2) */
428  /* we then add 1 to this DivChar to ensure than when we gues*/
429  /* we either guess correctly of under guess. */
430  /* _______________ */
431  /* aabbbbbb ) xxyyyyyyyy */
432  /* */
433  /* DivChar = aa + 1 */
434 
435  DivChar = *Num2 * 10; /* Divide char is the 1st 2 digits + 1 */
436  if (SaveRight->length > 1) /* more than 1 digit in Accum? */
437  {
438  DivChar += *(Num2 + 1); /* yes, get second digit for Div */
439  }
440  DivChar++; /* add 1 to Div number */
441  resultDigits = 0; /* initializes digit values to zero. */
442  thisDigit = 0;
443 
444  /* We are now to enter 2 do forever loops, inside the loops */
445  /* we test for ending conditions. and will exit the loops */
446  /* when needed. This inner loop may need to break out of */
447  /* both loops, if our divisor is reduced to zero(all finish*/
448  /* if this happens to do the no-no nad use a GOTO. */
449  /* The outer loop is used to obtain all digits for the resul*/
450  /* We continue in this loop while the divisor has NOT been */
451  /* reduced to zero and we have not reach the maximum number*/
452  /* of digits to be in the result (NumDigits + 1), we add */
453  /* one to NumDigits so we can round if necessary. */
454  /* The inner loop conputs each digits of the result and */
455  /* breaks to the outer loop when the next digit of result */
456  /* is found. */
457  /* We compute a digit of result by continually taking best */
458  /* guesses at how many times the dividend can go into the */
459  /* divisor. Once The divisor becomes less than the dividend*/
460  /* we found this digit and we exit the inner loop. If the */
461  /* divisor = dividend then we know dividend will go into */
462  /* 1 more than last guess, so bump up the last guess and */
463  /* exit both loops (ALL DONE !!), if neither of the above */
464  /* conditions are met our last guess was low, compute a new*/
465  /* guess using result of last one, and go though inner loop*/
466  /* again. */
467  for (; ; )
468  { /* do forever (outer loop) */
469  for (; ; )
470  { /* do forever (inner loop) */
471  /* are two numbers equal in length? */
472  if (SaveLeft->length == SaveRight->length)
473  {
474  /* yes, then compare two numbers */
475  rc = memcmp(Num1, Num2, SaveLeft->length);
476  if (rc < 0) /* is Num1(left) smaller? */
477  {
478  break; /* yes, break out of inner loop. */
479  }
480 
481  /* are the two numebrs equal and not */
482  /* doing // */
483  else if (rc == 0 && DivOP != OT_REMAINDER)
484  {
485  /* yes, done with Division, cleanup */
486  *resultPtr++ = (char)(thisDigit + 1);
487  resultDigits++; /* one more digit in result */
488  goto PowerDivideDone; /* break out of both loops. */
489  }
490  else /* Either rc >0 or doing // */
491  {
492  multiplier = *Num1; /* Lengths of nums are equal we only */
493  /* need to use 1 digits from divisor */
494  /* to this next guess. */
495  }
496  }
497  /* is left longer than Accum? */
498  else if (SaveLeft->length > SaveRight->length)
499  {
500  /* calculate multiplier, next two */
501  /*digits */
502  multiplier = *Num1 * 10 + *(Num1 + 1);
503  }
504  else
505  {
506  break; /* Divisor is smaller than dividend, */
507  }
508  /* we found this digit of result, go */
509  /* to outer loop and finish up */
510  /* processing for this digit. */
511  /* compute Multiplier for actual */
512  /*divide */
513  multiplier = multiplier * 10 / DivChar;
514  /* that is how many times will digit */
515  /* of dividend go into divisor, using*/
516  /* the 1st 2 digits of each number */
517  /* compute our Best Guess for this */
518  /* digit */
519  if (multiplier == 0) /* did it compute to 0? */
520  {
521  multiplier = 1; /* yes, can't be zero make it one. */
522  }
523  /* we know dividend goes into */
524  /* divisor at least one more time. */
525  thisDigit += multiplier; /* add multiplier to this digit. */
526 
527 
528  /* Go and actualy see if we guessed */
529  /* correctly, Divide digit through */
530  Num1 = subtractDivisor(Num1, SaveLeft->length, Num2, SaveRight->length, Num1 + SaveLeft->length - 1, (int)multiplier);
531  /* while we have leading zeros */
532  while (*Num1 == 0 && SaveLeft->length > 1)
533  {
534  Num1++; /* step to the next digit */
535  SaveLeft->length--; /* and reduce the length also */
536  }
537  /* end of inner loop, go back and */
538  /* guess again !! */
539  }
540  if (resultDigits || thisDigit)
541  { /* Have a digit for result? */
542  *resultPtr++ = (char) thisDigit; /* yes, place digit in result. */
543  thisDigit = 0; /* reset digit value to zero; */
544  resultDigits++; /* one more digit in result; */
545 
546  /* has dividend reduced to zero, */
547  /* run out of room for additional? */
548  if (*Num1 == '\0' || resultDigits > NumberDigits)
549  {
550  break; /* yes, were done, exit outer loop */
551  }
552 
553  }
554 
555  if (DivOP != OT_DIVIDE)
556  { /* Are we doing // or % */
557  if (CalcExp <= 0) /* have we finished integer part? */
558  {
559  break; /* yes, all done here, break out */
560  }
561  }
562  /* Was number reduced to zero? */
563  if (SaveLeft->length == 1 && *Num1 == '\0')
564  {
565  break; /* yes, all done exit outer loop */
566  }
567 
568 
569  /* we're not done dividing yet, we */
570  /* need to adjust expected exponent */
571  /* by one to the left */
572  CalcExp--; /* result exponent is one less. */
573  if (rightPadding > 0)
574  { /* are we still "padding" number for */
575  /* right number? */
576  SaveRight->length--; /* yes, length of right is one less. */
577  rightPadding--; /* now padding one less digit. */
578  }
579  else
580  {
581  SaveLeft->length++; /* length of left is now one more. */
582  }
583  } /* end of outer loop */
584 
585  PowerDivideDone: /* done doing actual divide now do */
586  ; /* the cleanup stuff. */
587 
588  if ((DivOP != OT_DIVIDE) && /* Is this a // or % operation, and */
589  (( CalcExp >= 0 && /* and is the result bad? */
590  ( resultDigits + CalcExp) > NumberDigits) ||
591  (CalcExp < 0 && (size_t)Numerics::abs(CalcExp) > resultDigits)))
592  {
593  /* yes, report the error and get out.*/
594  if (DivOP == OT_REMAINDER) /* remainder operation? */
595  {
597  }
598  else
599  {
601  }
602  }
603  if (DivOP == OT_REMAINDER)
604  { /* Are we doing // */
605  if (resultDigits)
606  { /* any numbers in result? */
607  if (*Num1)
608  { /* yes, but was it Zero? */
609  /* nope, we got a real remainder */
610  resultPtr = Num1; /* set result to point to remainder */
611  /* we need to compute the exponent */
612  /* of our result. */
613  SaveLeftPtr += left->length; /* point to end of input. */
614  /* point to existing location. */
615  SaveRightPtr = resultPtr + SaveLeft->length + adjustNum1;
616  /* Adjust for added Zeros. */
617  Accum->exp = left->exp - (SaveRightPtr - SaveLeftPtr);
618  Accum->length = SaveLeft->length; /* length of result is that of the */
619  /* remaining divisor digits. */
620  }
621  else
622  {
623  /* result is 0, just return it. */
624  return(RexxNumberString *)IntegerZero;
625  }
626  }
627  /* no digits in result, remainder is */
628  /* the left number (this) */
629  else
630  {
631  /* return a copy of Div(left) number */
632  result = this->clone();
633  result->setupNumber();
634  return result;
635  }
636  }
637  else
638  { /* real division... compute answer. */
639  if (resultDigits)
640  { /* any number in result? */
641  /* Set resultPtr to start of our */
642  /* buffer */
643  resultPtr = Output;
644  Accum->length = resultDigits; /* length is digits in result. */
645  Accum->exp = CalcExp; /* set exp to that calculated above. */
646  if (Accum->length > NumberDigits)
647  {/* is result too big? */
648  /* Yes, we need to adjust result */
649  /* increase exponent by amount over. */
650  Accum->exp += (Accum->length - NumberDigits);
651  Accum->length = NumberDigits; /* Length is same as Digits */
652  Accum->mathRound(resultPtr); /* round result if necessary. */
653  }
654  /* We now remove any trailing zeros */
655  /* point to last digit in result */
656  Num1 = resultPtr + Accum->length - 1;
657  while (!*Num1 && Accum->length)
658  { /* While there are trailing zeros */
659  Num1--; /* point to next character. */
660  Accum->length--; /* Result is one digit less. */
661  Accum->exp++; /* Adjust expont up one */
662  }
663  }
664  else
665  {
666  /* no digits in result answer is */
667  /* zero. */
668  return(RexxNumberString *)IntegerZero;
669  }
670  } /* End final processing */
671  result = new (Accum->length) RexxNumberString (Accum->length);
672 
673  result->length = Accum->length; /* set length of result */
674  result->exp = Accum->exp; /* set exponent of result. */
675  result->sign = Accum->sign; /* set sign of result. */
676  /* move result data to result area */
677  result->adjustPrecision(resultPtr, NumberDigits);
678  return result; /* all done, return to caller. */
679 }
680 
682 /*********************************************************************/
683 /* Function: Perform the Arithmetic power operation */
684 /*********************************************************************/
685 {
686  wholenumber_t powerValue;
687  wholenumber_t extra, OldNorm;
688  size_t NumberDigits;
689  char *Accum, *AccumPtr, *OutPtr, *TempPtr;
690  bool NegativePower;
691  RexxNumberStringBase *AccumObj;
692  RexxNumberString *left;
693  RexxNumberString *result;
694  size_t NumBits;
695  size_t AccumLen;
696 
697  NegativePower = false; /* Initialize the flags. */
698  requiredArgument(PowerObj, ARG_ONE); /* must have one argument */
699  /* get the whole number value */
700  if (!PowerObj->numberValue(powerValue, number_digits()))
701  {
703  }
704 
705  if (powerValue < 0)
706  { /* is the power negative? */
707  NegativePower = true; /* yes, mark for later. */
708  powerValue = -powerValue; /* make power positive, we first do */
709  /* power as if positive then */
710  /* invert value (1/x) */
711  }
712  NumberDigits = number_digits(); /* get the current Digits Setting. */
713  /* make a copy of self, since we may */
714  /* need to adjust some of its data. */
715  left = this->prepareOperatorNumber(NumberDigits+1, NumberDigits, NOROUND);
716 
717  if (left->sign == 0)
718  { /* Is the base number Zero? */
719  if (NegativePower) /* was power negative? */
720  {
721  /* this is a no no, report error. */
723  }
724  else if (powerValue == 0) /* Is power value zero? */
725  {
726  /* yes, return value of one */
727  return(RexxNumberString *)IntegerOne;
728  }
729  else /* otherwise power was positive */
730  {
731  /* return value of zero */
732  return(RexxNumberString *)IntegerZero;
733  }
734 
735  } /* Will the result exponent overflow?*/
736  if ((highBits(Numerics::abs(left->exp + left->length - 1)) +
737  highBits(Numerics::abs(powerValue)) + 1) > LONGBITS )
738  {
739  /* yes, report error and return. */
740  reportException(Error_Overflow_overflow, this, OREF_POWER, PowerObj);
741  }
742  /* Will the result overflow ? */
743  if (Numerics::abs((wholenumber_t)(left->exp + left->length - 1)) * powerValue > Numerics::MAX_EXPONENT)
744  {
745  /* yes, report error and return. */
746  reportException(Error_Overflow_overflow, this, OREF_POWER, PowerObj);
747  }
748 
749  if (powerValue != 0)
750  { /* a non-zero power value? */
751  /* yes, do the power operation. */
752  /* get storage for Accumulator data. */
754  memcpy(AccumObj, left, sizeof(RexxNumberStringBase));
755  /* initialize the Accumulator object.*/
756  /* this has all data of NumberString */
757  /* except the digits data */
758 
759  /* Find out how many digits are in */
760  /* power value, needed for actual */
761  /* precision value to be used in */
762  /* the computation. */
763  for (extra=0, OldNorm = powerValue; OldNorm ;extra++ )
764  {
765  OldNorm /= 10; /* Divide value by ten, keeping int */
766  }
767  NumberDigits += (extra + 1); /* adjust digits setting to reflect */
768 
769  /* size of buffers, for */
770  /*multiplication */
771  AccumLen = (2 * (NumberDigits+1)) + 1;
772  /* get storage for Output data */
773  OutPtr = buffer_alloc(AccumLen);
774  /* get storage for Accumulator Data */
775  Accum = buffer_alloc(AccumLen);
776  AccumPtr = Accum; /* Accum will point to start of */
777  /* storage block that AccumPtr is in.*/
778 
779  /* Initialize Accumulator digit data */
780  /* start with initial data. */
781  memcpy(AccumPtr, left->number, left->length);
782  /* The power operation is defined */
783  /* to use bitwise reduction */
784 
785  NumBits = LONGBITS; /* Get total number of bits in long */
786 
787  /* Find first non-zero left most bit */
788  while (!((size_t)powerValue & HIBIT))
789  {
790  powerValue <<= 1; /* bit is zero shift bits 1 to left */
791  NumBits--; /* one less bit. */
792  } /* endwhile */
793 
794  /* turn off this 1st 1-bit, already */
795  /* taken care of. Skip 1st Multiply */
796  powerValue = (wholenumber_t) ((size_t)powerValue & LOWBITS);
797 
798  while (NumBits--)
799  { /* while 1-bits remain in power. */
800  if ((size_t) powerValue & HIBIT)
801  { /* is left most bit a 1? */
802  /* yes, we need to multiply number by*/
803  /* Acummulator. */
804  /* go do multiply. AccumPtr will get*/
805  /* assigned result of multiply */
806  AccumPtr = multiplyPower(AccumPtr, AccumObj, left->number, (RexxNumberStringBase *) left, OutPtr, AccumLen, NumberDigits);
807  /* We now call AdjustNumber to make */
808  /* sure we stay within the required */
809  /* precision and move the Accum */
810  /* data back to Accum. */
811  AccumPtr = AccumObj->adjustNumber(AccumPtr, Accum, AccumLen, NumberDigits);
812  }
813  if (NumBits)
814  { /* any 1-bits left in power? */
815  /* yes, we need to Square the Accum */
816  /* go do multiply. AccumPtr will get*/
817  /* assigned result of squaring */
818  AccumPtr = multiplyPower(AccumPtr, AccumObj, AccumPtr, AccumObj, OutPtr, AccumLen, NumberDigits);
819  /* We now call AdjustNumber to make */
820  /* sure we stay within the required */
821  /* precision and move the Accum */
822  /* data back to Accum. */
823  AccumPtr = AccumObj->adjustNumber(AccumPtr, Accum, AccumLen, NumberDigits);
824  }
825  powerValue <<= 1; /* shift power bits one to the left */
826  } /* Finished with Power 1st step. */
827 
828  if (NegativePower)
829  { /* is this a negative power operation*/
830  /* yes, so we need to invert value. */
831  AccumPtr = dividePower(AccumPtr, AccumObj, Accum, NumberDigits);
832  }
833 
834  NumberDigits -= (extra + 1); /* reset digits setting to original; */
835  /* Remove all leading zeros. */
836  AccumPtr = AccumObj->stripLeadingZeros(AccumPtr);
837 
838  /* Is result bigger than digits? */
839  if (AccumObj->length > NumberDigits)
840  {
841  /* Yes, we need to adjust result */
842  /* increase exponent by amount over. */
843  AccumObj->exp += (AccumObj->length - NumberDigits);
844  AccumObj->length = NumberDigits; /* Length is same as Digits */
845  AccumObj->mathRound(AccumPtr); /* round result if necessary. */
846  }
847  /* We now remove any trailing blanks */
848  /* point to last digit in result */
849  TempPtr = AccumPtr + AccumObj->length -1;
850  /* While there are trailing zeros */
851  while (!*TempPtr && AccumObj->length)
852  {
853  TempPtr--; /* point to next character. */
854  AccumObj->length--; /* Result is one digit less. */
855  AccumObj->exp++; /* Adjust expont up one */
856  }
857 
858  /* get new numberString Object for */
859  /* result length. No initial Data */
860  result = new (AccumObj->length) RexxNumberString (AccumObj->length);
861 
862  result->sign = AccumObj->sign; /* fill in the data of result from */
863  result->exp = AccumObj->exp; /* AccumObj. */
864  result->length = AccumObj->length;
865  /* copy digit data from AccumPtr. */
866  memcpy(result->number, AccumPtr, result->length);
867  }
868  else
869  { /* Power value is zero. */
870  /* result is 1. */
871  result = (RexxNumberString *)IntegerOne;
872  }
873  return result; /* return our result object. */
874 }
875 
877  char *rightPtr, RexxNumberStringBase *right,
878  char *OutPtr, size_t OutLen, size_t NumberDigits)
879 /*********************************************************************/
880 /* Function: Multiply numbers for the power operation */
881 /*********************************************************************/
882 {
883  char *current, *resultPtr;
884  char *AccumPtr = NULL;
885  char MultChar;
886  size_t AccumLen;
887  size_t i;
888  size_t ExtraDigit;
889 
890 
891  memset(OutPtr, '\0', OutLen); /* make output area is all zeros. */
892 
893  AccumLen = 0; /* no data at this time. */
894  resultPtr = OutPtr + OutLen - 1; /* Set up result, point to end of */
895  /* data. */
896  /* Set up digit ptr. small num */
897  current = rightPtr + right->length; /* get last digit of number. */
898 
899  for (i = right->length ; i ; i-- )
900  { /* do for all multiplier digits */
901  current--; /* shift add location by 1. */
902  MultChar = *current; /* get new multiplier digit. */
903  if (MultChar) /* is this new digit a Zero? */
904  {
905  /* nope, do multiplication of this */
906  /* digit */
907  AccumPtr = addMultiplier(leftPtr, left->length, resultPtr, MultChar);
908  }
909  resultPtr--; /* Backup Result Ptr, for next digit */
910  } /* go do next digit. */
911  /* Get length of computed number. */
912  AccumLen = (size_t)(++resultPtr - AccumPtr) + right->length;
913 
914  /* AccumPtr now points to result, and*/
915  /* the len of result is in AccumLen */
916 
917  /* We will now get a real Object */
918  if (AccumLen > NumberDigits)
919  { /* Is result len greater then Digits */
920  ExtraDigit = AccumLen - NumberDigits;/* Yes, save amount over for exp */
921  }
922  else
923  {
924  ExtraDigit = 0; /*Length OK, no adjusting Exp. */
925  }
926 
927  /* compute the resulting Exponent */
928  left->exp += (right->exp + ExtraDigit);
929  left->sign *= right->sign; /* Compute the Sign */
930  left->length = AccumLen; /* Set length of result. */
931 
932 
933  return AccumPtr; /* return Pointer to result digits. */
934 } /* All done, */
935 
936 char *RexxNumberString::dividePower(char *AccumPtr, RexxNumberStringBase *Accum, char *Output, size_t NumberDigits)
937 /*********************************************************************/
938 /* Function: Invert number from the power operation */
939 /*********************************************************************/
940 {
941  RexxNumberStringBase *left;
942  char leftBuffer[sizeof(RexxNumberStringBase)];
943  char *Num1, *Num2;
944  char *resultPtr, *leftPtr, *result;
945  int multiplier, rc;
946  int DivChar, thisDigit;
947  wholenumber_t CalcExp;
948  size_t resultDigits;
949  size_t totalDigits;
950 
951  /* NOTE: this routine if very similiar to the Division */
952  /* routine, these we kept as seperate routines since there*/
953  /* are enough subtile differences between the operations */
954  /* that combining them would make an already complex */
955  /* routine even more so. When fixing/updating/adding to */
956  /* this routin also check Division for similiar updates*/
957 
958  totalDigits = ((NumberDigits + 1) * 2) + 1;
959  /* get buffer for left digit data. */
960  leftPtr = buffer_alloc(totalDigits);
961  /* get buffer for result digit data. */
962  result = buffer_alloc(totalDigits);
963  resultPtr = result; /* Set up the result, point to end of*/
964  /* data. */
965  /* address the static part */
966  left = (RexxNumberStringBase *)leftBuffer;
967 
968  /* length of left starts same as */
969  /* Accum */
970  left->length = Accum->length;
971  left->exp = 0; /* no exponent to start with. */
972  *leftPtr = 1; /* place the digit 1 into left. */
973  /* fill the rest of data with Zero */
974  memset(leftPtr + 1, '\0', totalDigits - 1);
975  /* calculate expected resultant exp */
976  CalcExp = -Accum->exp - (wholenumber_t)Accum->length + 1;
977 
978  Num1 = leftPtr; /* Num1 will be left digit pointer. */
979  Num2 = AccumPtr; /* Num2 is our input digit pointer */
980 
981  /* When generate a best guess digits for result we will look*/
982  /* use the 1st 2 digits of the dividend (if there are 2) */
983  /* we then add 1 to this DivChar to ensure than when we gues*/
984  /* we either guess correctly of under guess. */
985  /* _______________ */
986  /* aabbbbbb ) xxyyyyyyyy */
987  /* */
988  /* DivChar = aa + 1 */
989 
990  DivChar = *Num2 * 10; /* Divide char is 1st 2 digits + 1 */
991  if (Accum->length > 1) /* more than 1 digit in Accum? */
992  DivChar += *(Num2 + 1); /* yes, get second digit for Div */
993  DivChar++; /* add 1 to Div number */
994 
995  resultDigits = 0; /* initializes digit values to zero. */
996  thisDigit = 0;
997 
998  /* We are now to enter 2 do forever loops, inside the loops */
999  /* we test for ending conditions. and will exit the loops */
1000  /* when needed. This inner loop may need to break out of */
1001  /* both loops, if our divisor is reduced to zero(all finish*/
1002  /* if this happens to do the no-no nad use a GOTO. */
1003  /* The outer loop is used to obtain all digits for the resul*/
1004  /* We continue in this loop while the divisor has NOT been */
1005  /* reduced to zero and we have not reach the maximum number*/
1006  /* of digits to be in the result (NumDigits + 1), we add */
1007  /* one to NumDigits so we can round if necessary. */
1008  /* The inner loop conputs each digits of the result and */
1009  /* breaks to the outer loop when the next digit of result */
1010  /* is found. */
1011  /* We compute a digit of result by continually taking best */
1012  /* guesses at how many times the dividend can go into the */
1013  /* divisor. Once The divisor becomes less than the dividend*/
1014  /* we found this digit and we exit the inner loop. If the */
1015  /* divisor = dividend then we know dividend will go into */
1016  /* 1 more than last guess, so bump up the last guess and */
1017  /* exit both loops (ALL DONE !!), if neither of the above */
1018  /* conditions are met our last guess was low, compute a new*/
1019  /* guess using result of last one, and go though inner loop*/
1020  /* again. */
1021  for (; ; )
1022  { /* do forever (outer loop) */
1023  for (; ; )
1024  { /* do forever (inner loop) */
1025  /* are two numbers equal in length? */
1026  if (left->length == Accum->length)
1027  {
1028  /* yes, then compare the two numbers */
1029  rc = memcmp(Num1, Num2, left->length);
1030  if (rc < 0) /* is Num1(left) smaller? */
1031  {
1032  break; /* yes, break out of inner loop. */
1033  }
1034 
1035  else if (rc == 0)
1036  { /* are the two numebrs equal */
1037  /* yes, done with Division, cleanup */
1038  *resultPtr++ = (char)(thisDigit + 1);
1039  resultDigits++; /* one more digit in result */
1040  goto PowerDivideDone; /* break out of both loops. */
1041  }
1042  else
1043  {
1044  multiplier = *Num1; /* Num2(Accum) is smaller, */
1045  }
1046  }
1047  /* is left longer than Accum? */
1048  else if (left->length > Accum->length)
1049  {
1050  /* calculate multiplier, next two */
1051  /*digits */
1052  multiplier = *Num1 * 10 + *(Num1 + 1);
1053  }
1054  else
1055  {
1056  break; /* left is smaller, break inner loop */
1057  }
1058 
1059  /* compute Multiplier for divide */
1060  multiplier = multiplier * 10 / DivChar;
1061  if (multiplier == 0) /* did it compute to 0? */
1062  {
1063  multiplier = 1; /* yes, can't be zero make it one. */
1064  }
1065 
1066  thisDigit += multiplier; /* add multiplier to this digit. */
1067  /* now subtract */
1068  Num1 = subtractDivisor(Num1, left->length, Num2, Accum->length, Num1 + left->length - 1, multiplier);
1069  /* Strip off all leading zeros */
1070  Num1 = left->stripLeadingZeros(Num1);
1071  } /* end of inner loop */
1072 
1073  if (resultDigits || thisDigit)
1074  { /* Have a digit for result? */
1075  *resultPtr++ = (char) thisDigit; /* yes, place digit in result. */
1076  thisDigit = 0; /* reset digit value to zero; */
1077  resultDigits++; /* one more digit in result; */
1078 
1079  /* is there been reduced to zero */
1080  if (*Num1 == '\0' || resultDigits > NumberDigits)
1081  {
1082  break; /* yes, were done, exit outer loop */
1083  }
1084 
1085  }
1086  /* Was number reduced to zero? */
1087  if (left->length == 1 && *Num1 == '\0')
1088  {
1089  break; /* yes, all done exit outer loop */
1090  }
1091 
1092  CalcExp--; /* result exponent is one less. */
1093  left->length++; /* length is one more. */
1094 
1095  /* reset the number ptr to beginning */
1096  /* of the buffer. */
1097  Num1 = (char *)memmove(leftPtr, Num1, left->length);
1098  /* make sure traling end of buffer */
1099  /* is reset to 0's. */
1100  memset(Num1 + left->length, '\0', totalDigits - left->length);
1101  } /* end of outer loop */
1102 
1103  PowerDivideDone: /*All done doing divide now do */
1104  ; /* the cleanup stuff. */
1105 
1106  Accum->length = resultDigits; /* set length of result */
1107  Accum->exp = CalcExp; /* set exponent of result. */
1108  memcpy(Output, result, resultDigits); /* move result data to result area */
1109  return Output; /* all done, return to caller. */
1110 }
RexxNumberStringBase::length
size_t length
Definition: NumberStringClass.hpp:90
RexxNumberStringBase::RexxNumberStringBase
RexxNumberStringBase()
Definition: NumberStringClass.hpp:79
RexxNumberString::power
RexxNumberString * power(RexxObject *)
Definition: NumberStringMath2.cpp:681
RexxNumberString::Division
RexxNumberString * Division(RexxNumberString *, unsigned int)
Definition: NumberStringMath2.cpp:292
Error_Overflow_power
#define Error_Overflow_power
Definition: RexxErrorCodes.h:380
RexxNumberString::prepareOperatorNumber
RexxNumberString * prepareOperatorNumber(size_t, size_t, bool)
Definition: NumberStringMath.cpp:432
RexxNumberString::setupNumber
void setupNumber()
Definition: NumberStringClass.hpp:191
RexxNumberString::highBits
static size_t highBits(size_t)
Definition: NumberStringMath.cpp:249
ActivityManager.hpp
RexxNumberString::addMultiplier
static char * addMultiplier(char *, size_t, char *, int)
Definition: NumberStringMath2.cpp:57
requiredArgument
void requiredArgument(RexxObject *object, size_t position)
Definition: RexxCore.h:284
FASTDIGITS
#define FASTDIGITS
Definition: NumberStringMath.hpp:77
new_numberstring
RexxNumberString * new_numberstring(const char *s, stringsize_t l)
Definition: NumberStringClass.hpp:274
reportException
void reportException(wholenumber_t error)
Definition: ActivityManager.hpp:136
Error_Invalid_whole_number_power
#define Error_Invalid_whole_number_power
Definition: RexxErrorCodes.h:221
OT_DIVIDE
#define OT_DIVIDE
Definition: NumberStringMath.hpp:52
Error_Overflow_overflow
#define Error_Overflow_overflow
Definition: RexxErrorCodes.h:374
IntegerZero
#define IntegerZero
Definition: RexxCore.h:188
OT_INT_DIVIDE
#define OT_INT_DIVIDE
Definition: NumberStringMath.hpp:53
RexxNumberStringBase::adjustNumber
char * adjustNumber(char *, char *, size_t, size_t)
Definition: NumberStringMath.cpp:274
OT_REMAINDER
#define OT_REMAINDER
Definition: NumberStringMath.hpp:54
ARG_ONE
const int ARG_ONE
Definition: RexxCore.h:80
ArrayClass.hpp
RexxNumberStringBase::stripLeadingZeros
char * stripLeadingZeros(char *)
Definition: NumberStringMath.cpp:308
NumberStringClass.hpp
Error_Overflow_zero
#define Error_Overflow_zero
Definition: RexxErrorCodes.h:376
NumberStringMath.hpp
IntegerOne
#define IntegerOne
Definition: RexxCore.h:189
HIBIT
#define HIBIT
Definition: NumberStringMath.hpp:71
buffer_alloc
#define buffer_alloc(s)
Definition: NumberStringMath.hpp:75
RexxObject::numberValue
virtual bool numberValue(wholenumber_t &result, size_t precision)
Definition: ObjectClass.cpp:963
RexxNumberString::number
char number[4]
Definition: NumberStringClass.hpp:269
RexxNumberString
Definition: NumberStringClass.hpp:93
RexxNumberStringBase::sign
short sign
Definition: NumberStringClass.hpp:86
wholenumber_t
ssize_t wholenumber_t
Definition: rexx.h:229
NOROUND
#define NOROUND
Definition: NumberStringMath.hpp:68
RexxNumberString::checkNumber
RexxNumberString * checkNumber(size_t digits)
Definition: NumberStringClass.hpp:166
number_digits
size_t number_digits()
Definition: Numerics.hpp:147
LOWBITS
#define LOWBITS
Definition: NumberStringMath.hpp:72
RexxNumberStringBase::mathRound
void mathRound(char *)
Definition: NumberStringMath.cpp:153
Error_Invalid_whole_number_intdiv
#define Error_Invalid_whole_number_intdiv
Definition: RexxErrorCodes.h:228
RexxNumberString::Multiply
RexxNumberString * Multiply(RexxNumberString *)
Definition: NumberStringMath2.cpp:101
RexxNumberString::adjustPrecision
void adjustPrecision(char *, size_t)
Definition: NumberStringMath.cpp:324
Error_Invalid_whole_number_rem
#define Error_Invalid_whole_number_rem
Definition: RexxErrorCodes.h:229
RexxNumberString::dividePower
static char * dividePower(char *AccumPtr, RexxNumberStringBase *Accum, char *Output, size_t NumberDigits)
Definition: NumberStringMath2.cpp:936
RexxActivity.hpp
RexxNumberStringBase
Definition: NumberStringClass.hpp:77
RexxNumberString::clone
RexxNumberString * clone()
Definition: NumberStringClass.cpp:114
RexxCore.h
RexxNumberString::subtractDivisor
static char * subtractDivisor(char *data1, size_t length1, char *data2, size_t length2, char *result, int Mult)
Definition: NumberStringMath2.cpp:203
LONGBITS
#define LONGBITS
Definition: NumberStringMath.hpp:66
RexxNumberStringBase::exp
wholenumber_t exp
Definition: NumberStringClass.hpp:89
Numerics::MAX_EXPONENT
static const wholenumber_t MAX_EXPONENT
Definition: Numerics.hpp:64
Numerics::abs
static wholenumber_t abs(wholenumber_t n)
Definition: Numerics.hpp:115
RexxNumberString::multiplyPower
static char * multiplyPower(char *leftPtr, RexxNumberStringBase *left, char *rightPtr, RexxNumberStringBase *right, char *OutPtr, size_t OutLen, size_t NumberDigits)
Definition: NumberStringMath2.cpp:876
BufferClass.hpp
if
if(!yymsg) yymsg
RexxObject
Definition: ObjectClass.hpp:311