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)  

NumberStringMath.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 okmath.c */
40 /* */
41 /* Arithemtic function for the NumberString Class */
42 /* */
43 /******************************************************************************/
44 #include <ctype.h>
45 #include <stdlib.h>
46 #include <string.h>
47 
48 #include "RexxCore.h"
49 #include "StringClass.hpp"
50 #include "NumberStringClass.hpp"
51 #include "ArrayClass.hpp"
52 #include "RexxActivity.hpp"
53 #include "BufferClass.hpp"
54 #include "NumberStringMath.hpp"
55 #include "ActivityManager.hpp"
56 #include "ProtectedObject.hpp"
57 
58 
59 RexxNumberString *RexxNumberString::maxMin(RexxObject **args, size_t argCount, unsigned int operation)
60 /*********************************************************************/
61 /* Function: Process the MAX and MIN builtin functions and methods */
62 /*********************************************************************/
63 {
64  size_t arg;
65  RexxNumberString *compobj, *maxminobj;
66  RexxInteger *compResult;
67  RexxObject *nextObject;
68  size_t saveFuzz, saveDigits;
69 
70  if (argCount == 0) return this; /* any arguments to ccompare? */
71 
72  /* Get a reference to our current act*/
74 
75  saveFuzz = CurrentActivation->fuzz(); /* get the current fuzz and digits */
76  saveDigits = CurrentActivation->digits();
77  CurrentActivation->setFuzz(0); /* set the fuzz setting to 0 */
78 
79  /* assume 1st operand (self) is the */
80  /* one we want ! */
81  // NB: The min and max methods are defined as rounding the values to the
82  // current digits settings, which bypasses the LOSTDIGITS condition
83  maxminobj = this->prepareNumber(saveDigits, ROUND);
84  ProtectedObject p(maxminobj);
85  for (arg=0; arg < argCount; arg++)
86  { /* Loop through all args */
87  nextObject = args[arg]; /* Get next argument. */
88 
89  if (nextObject == OREF_NULL)
90  { /* Was this arg omitted? */
91  /* Yes, report the error. */
92  /* but restore the fuzz first */
93  CurrentActivation->setFuzz(saveFuzz);
94  if (operation == OT_MAX) /* doing a MAX operation? */
95  {
97  }
98  else /* nope must be min. */
99  {
101  }
102  }
103 
104  compobj = nextObject->numberString();/* get a numberstring object */
105  if (compobj != OREF_NULL)
106  { /* Was conversion sucessfull? */
107  /* get new comp object in right */
108  /* digits */
109  compobj = compobj->prepareOperatorNumber(saveDigits, saveDigits, ROUND);
110 
111  /* Just compare the two NumberStrings*/
112  /* See if new number is greater than*/
113  /* See if we have a new MAX */
114  if (operation == OT_MAX)
115  {
116  compResult = compobj->isGreaterThan(maxminobj);
117 
118  }
119  else
120  { /* must be looking for MIN */
121  /* is new less than old maxmin */
122  /* if so we have a new maxmin. */
123  compResult = compobj->isLessThan(maxminobj);
124  }
125 
126 
127  if (compResult == TheTrueObject)
128  { /* Do we have a new MAX/MIN ? */
129  /* Yes, no need to save old MAX/MIN */
130  /* assign and protect our next */
131  /* MAX/MIN */
132  p = compobj;
133  maxminobj = (RexxNumberString *)compobj;
134  }
135  }
136  else
137  { /* invalid object type. */
138  /* be sure we restore original Fuzz */
139  CurrentActivation->setFuzz(saveFuzz);
140  /* keep maxminobj around just a */
141  reportException(Error_Incorrect_method_number, arg + 1, args[arg]);
142  }
143  }
144  CurrentActivation->setFuzz(saveFuzz); /* be sure we restore original Fuzz */
145  /* We have already made a */
146  /* copy/converted the MaxMin object */
147  /* and it is adjusted to the correct */
148  /* precision, so we have nothing */
149  /* left to do. */
150  return maxminobj; /* now return it. */
151 }
152 
154  char *NumPtr) /* first digit to round up */
155 /*********************************************************************/
156 /* Function: Adjust a a number string object to correct NUMERIC */
157 /* DIGITS setting */
158 /*********************************************************************/
159 {
160  int carry, RoundNum;
161  size_t resultDigits;
162  wholenumber_t numVal;
163 
164  resultDigits = this->length; /* get number of digits in number */
165  NumPtr += this->length; /* point one past last digit, this */
166  /* gives us most significant digit of*/
167  /* digits being truncated. */
168 
169  if (*NumPtr-- >= 5 )
170  { /* is this digit grater_equal to 5 */
171  carry = 1; /* yes, we need to round up next dig */
172  while (carry && resultDigits-- > 0)
173  {/* do while we have carry and digits */
174  /* left to round up in number */
175  if (*NumPtr == 9) /* is this digit 9? */
176  {
177  RoundNum = 0; /* Yes, then this digit will be 0 */
178  }
179  else
180  {
181  RoundNum = *NumPtr + carry; /* Not 9, add 1 (carry) to digit */
182  carry = 0; /* no more carry. */
183  }
184  *NumPtr-- = (char)RoundNum; /* Set this digit in data area. */
185  }
186 
187  if (carry )
188  { /* Done will all numbers, do we still*/
189  /* have a carry (Did carry propogate */
190  /* all the way through? */
191  *++NumPtr = 1; /* yes, set high digit to 1 */
192  this->exp += 1; /* increment exponent by one. */
193  }
194  }
195 
196  /* At this point number is all setup,*/
197  /* Check for overflow */
198  numVal = this->exp + this->length - 1;
199  if (numVal > Numerics::MAX_EXPONENT)
200  {
202  }
203  /* Check for underflow. */
204  else if (this->exp < Numerics::MIN_EXPONENT)
205  {
207  }
208  return;
209 }
210 
212 /*********************************************************************/
213 /* Function: Adjust the precision of a number to the given digits */
214 /*********************************************************************/
215 {
216  wholenumber_t resultVal;
217  /* is length of number too big? */
218  if (this->length > NumDigits)
219  {
220  size_t extra = this->length - NumDigits;
221  this->length = NumDigits; /* Yes, make length equal precision */
222  this->exp += extra; /* adjust exponent by amount over */
223  this->mathRound(number); /* Round the adjusted number */
224  }
225 
226  /* Was number reduced to zero? */
227  if (*number == 0 && this->length == 1)
228  {
229  this->setZero(); /* Yes, make it so... */
230  }
231  else
232  {
233 
234  /* At this point number is all setup,*/
235  /* Check for overflow */
236  resultVal = this->exp + this->length - 1;
237  if (resultVal > Numerics::MAX_EXPONENT)
238  {
240  }
241  else if (this->exp < Numerics::MIN_EXPONENT)
242  { /* Check for underflow. */
244  }
245  }
246  return; /* just return to caller. */
247 }
248 
249 size_t RexxNumberString::highBits(size_t number)
250 /*********************************************************************/
251 /* Function: Determine high order bit position of an unsigned */
252 /* number setting. */
253 /*********************************************************************/
254 {
255  size_t HighBit;
256 
257  if (number == 0) /* is number 0? */
258  {
259  return 0; /* Yes, just return 0, no high bit */
260  }
261 
262  HighBit = LONGBITS; /* get number of digits in number */
263 
264  while ((number & HIBIT) == 0)
265  { /* loops though all bit positions */
266  /* until first 1 bit is found. */
267  number <<= 1; /* shift number one bit pos left. */
268  HighBit--; /* decrement i, high bit not found */
269  }
270 
271  return HighBit; /* return count. */
272 }
273 
275  char *NumPtr, /* pointer to number data */
276  char *result, /* result location */
277  size_t resultLen, /* result length */
278  size_t NumberDigits) /* required digits setting */
279 /*********************************************************************/
280 /* Function: Adjust the number data to be with the correct NUMERIC */
281 /* DIGITS setting. */
282 /*********************************************************************/
283 {
284  /* Remove all leading zeros */
285  NumPtr = this->stripLeadingZeros(NumPtr);
286 
287  /* is length of number too big? */
288  if (this->length > NumberDigits)
289  {
290  this->length = NumberDigits; /* Yes, make length equal precision */
291  /* adjust exponent by amount over */
292  this->exp += this->length - NumberDigits;
293  this->mathRound(NumPtr); /* Round the adjusted number */
294  }
295 
296  if (resultLen == 0) /* See if there is anything to copy? */
297  {
298  return result; /* Nope, just return result Pointer. */
299  }
300  else
301  {
302  /* Copy the data into the result area*/
303  /* and pointer to start of data */
304  return(char *)memcpy(((result + resultLen - 1) - this->length), NumPtr, this->length);
305  }
306 }
307 
309  char *AccumPtr) /* current accumulator position */
310 /*********************************************************************/
311 /* Function: Remove all leading zeros from a number */
312 /*********************************************************************/
313 {
314  /* while leading digit is zero and */
315  /* still data in object */
316  while (!*AccumPtr && this->length>1)
317  {
318  AccumPtr++; /* Point to next digit. */
319  this->length--; /* length od number is one less. */
320  }
321  return AccumPtr; /* return pointer to 1st non-zero */
322 }
323 
324 void RexxNumberString::adjustPrecision(char *resultPtr, size_t NumberDigits)
325 /*********************************************************************/
326 /* Function: Adjust the precision of a number to the given digits */
327 /*********************************************************************/
328 {
329  bool CopyData;
330  wholenumber_t resultVal;
331  /* resultPtr will either point to */
332  /* the actual result data or be */
333  /* NULL, if the data is already in */
334  /* result obj. */
335  if (resultPtr == NULL)
336  { /* Is resultPtr NULL, that is data */
337  /* already in result object? */
338  CopyData = false; /* Yes, don't copy data. */
339  /* have data pointer point to data in*/
340  resultPtr = this->number; /* The result object. */
341  }
342  else
343  {
344  CopyData = true; /* resultPtr not null, need to copy */
345  }
346  /* is length of number too big? */
347  if (this->length > NumberDigits)
348  {
349  size_t extra = this->length - NumberDigits;
350  this->length = NumberDigits; /* Yes, make length equal precision */
351  this->exp += extra; /* adjust exponent by amount over */
352  this->mathRound(resultPtr); /* Round the adjusted number */
353  }
354 
355  if (CopyData)
356  { /* only remove leading zeros if */
357  /* data note already in the object. */
358  /* remove any leading zeros */
359  resultPtr = this->stripLeadingZeros(resultPtr);
360  /* Move result data into object */
361  memcpy(this->number, resultPtr, (size_t)this->length);
362  }
363 
364  /* make sure this number has the correct numeric settings */
365  setNumericSettings(NumberDigits, number_form());
366 
367  if (!*resultPtr && this->length == 1) /* Was number reduced to zero? */
368  this->setZero(); /* Yes, make it so... */
369  else
370  {
371 
372  /* At this point number is all setup,*/
373  /* Check for overflow */
374  resultVal = this->exp + this->length - 1;
375  if (resultVal > Numerics::MAX_EXPONENT)
376  {
378  }
379  else if (this->exp < Numerics::MIN_EXPONENT)
380  { /* Check for underflow. */
382  }
383  }
384  return; /* just return to caller. */
385 }
386 
387 
388 RexxNumberString *RexxNumberString::prepareNumber(size_t NumberDigits, bool rounding)
389 /*********************************************************************/
390 /* Function: Create new copy of supplied object and make sure the */
391 /* number is computed to correct digits setting */
392 /*********************************************************************/
393 {
394  /* clone ourselves */
395  RexxNumberString *newObj = this->clone();
396  if (newObj->length > NumberDigits)
397  {
398  // NOTE: This version does NOT raise a LOSTDIGITS condition, since it
399  // is used for formatting results from functions that are used to create
400  // intentionally shortened numbers.
401 
402  /* adjust exponent by amount over */
403  /* precision */
404  newObj->exp += newObj->length - NumberDigits;
405  newObj->length = NumberDigits; /* make length equal precision */
406  if (rounding == ROUND)
407  { /* are we to perform rounding? */
408  /* Round the adjusted number */
409  newObj->mathRound(newObj->number);
410  }
411  }
412  /* make sure this has the correct settings */
413  newObj->setNumericSettings(NumberDigits, number_form());
414  return newObj; /* return new object to caller. */
415 }
416 
417 
432 RexxNumberString *RexxNumberString::prepareOperatorNumber(size_t targetLength, size_t numberDigits, bool rounding)
433 /*********************************************************************/
434 /* Function: Create new copy of supplied object and make sure the */
435 /* number is computed to correct digits setting */
436 /*********************************************************************/
437 {
438  /* clone ourselves */
439  RexxNumberString *newObj = this->clone();
440  if (newObj->length > numberDigits)
441  { /* is the length larger than digits()*/
442  /* raise a numeric condition, may */
443  /* not return from this. */
444  reportCondition(OREF_LOSTDIGITS, (RexxString *)newObj);
445  if (newObj->length > targetLength)
446  {
447  /* adjust exponent by amount over */
448  /* precision */
449  newObj->exp += newObj->length - targetLength;
450  newObj->length = targetLength; /* make length equal precision */
451  if (rounding == ROUND)
452  { /* are we to perform rounding? */
453  /* Round the adjusted number */
454  newObj->mathRound(newObj->number);
455  }
456  }
457  }
458  /* make sure this has the correct settings */
459  newObj->setNumericSettings(numberDigits, number_form());
460  return newObj; /* return new object to caller. */
461 }
462 
463 
465  RexxNumberString *other, /* other addition/subtract target */
466  unsigned int operation, /* add or subtract operation */
467  size_t NumberDigits ) /* precision to use */
468 /*********************************************************************/
469 /* Function: Add or subtract two normalized numbers */
470 /*********************************************************************/
471 {
472  RexxNumberString *left, *right, *result, *temp1;
473  char *leftPtr,*rightPtr,*resultPtr;
474  char *resultBuffer = NULL;
475  int right_sign, carry, addDigit, rc;
476  wholenumber_t LadjustDigits, RadjustDigits;
477  wholenumber_t adjustDigits;
478  size_t ResultSize;
479  wholenumber_t aLeftExp, aRightExp, rightExp, leftExp, MinExp;
480  size_t rightLength, leftLength;
481  char resultBufFast[FASTDIGITS*2+1]; /* for fast allocation if default */
482  size_t maxLength = NumberDigits + 1;
483 
484  /* Make copies of the input object */
485  /* since we may need to adjust */
486  /* values, and make these new */
487  /*objects safe. */
488  left = this;
489  right = other;
490  leftExp = left->exp; /* maintain our own copy of exponent */
491  rightExp = right->exp; /* these may be adjusted below. */
492 
493  leftLength = left->length; /* maintain our own copy of lengths */
494  rightLength = right->length; /* these may be adjusted below. */
495 
496  if (leftLength > NumberDigits)
497  {
498  // raise a numeric condition, which might not return
499  reportCondition(OREF_LOSTDIGITS, (RexxString *)this);
500  if (leftLength > maxLength)
501  {
502  leftExp += leftLength - maxLength;
503  leftLength = maxLength;
504  }
505  }
506 
507  if (rightLength > NumberDigits)
508  {
509  // raise a numeric condition, which might not return
510  reportCondition(OREF_LOSTDIGITS, (RexxString *)other);
511  if (rightLength > maxLength)
512  {
513  /* not return from this. */
514  rightExp += rightLength - maxLength;
515  rightLength = maxLength;
516  }
517  }
518 
519 
520  if (leftExp <= rightExp) /* Find the smaller of the two exps. */
521  {
522  MinExp = leftExp;
523  }
524  else
525  {
526  MinExp = rightExp;
527  }
528 
529 
530  aLeftExp = leftExp - MinExp; /* Compute adjusted Left exponent */
531  aRightExp = rightExp - MinExp; /* Compute adjusted Right exponent */
532  right_sign = right->sign; /* make a copy of the right objs sign*/
533  /* Now check if either number is */
534  /* zero or has dominance over */
535  /* the other number. */
536  temp1=NULL;
537  if (left->sign==0)
538  { /* Is left number zero */
539  temp1=right; /* Yes, set up to return right */
540  }
541  else if (right->sign==0)
542  { /* Is right number zero ? */
543  temp1=left; /* Yes, Setup up to return left */
544 
545  /* Is the left number completely */
546  /* dominant, that is can the right */
547  /* number affect the outcome of the */
548  /* arithmetic operation? */
549  }
550  else if ((aLeftExp + (wholenumber_t)leftLength) > (wholenumber_t)(rightLength + NumberDigits))
551  {
552  temp1=left; /* Yes, so return the left number.*/
553  /* Is the right number completely */
554  /* dominant, that is can the left */
555  /* number affect the outcome of the */
556  /* arithmetic operation? */
557  }
558  else if ((aRightExp + (wholenumber_t)rightLength) > (wholenumber_t)(leftLength + NumberDigits))
559  {
560  temp1=right; /* Yes, so setup to return right */
561  }
562  /* Temp1 will either point to null */
563  /* or to the number object that */
564  /* should be returned as the result. */
565  /* A null means we really do need to */
566  /* do that math. */
567  if (temp1)
568  { /* Can we do a quick return? */
569  result = temp1->clone(); /* Yes, copy temp1 for result */
570 
571  /* are we doing subtraction and */
572  /* the right operand is our result? */
573  if ((temp1 == right) && (operation == OT_MINUS))
574  {
575  result->sign = -result->sign; /* yes, make sign of result oposite */
576  }
577  /* of the right operand. */
578  /* Get result into correct precision.*/
579  result->setupNumber();
580  return result; /* and return new result object */
581  }
582  /* We really need to perfrom the */
583  /* arithmetic, so lets do it. */
584  if (operation == OT_MINUS)
585  { /* is this a subtraction request? */
586  right_sign = -right_sign; /* yes, invert sign of right number */
587  /* to make addition. */
588  }
589 
590  if (right_sign != left->sign)
591  { /* are the two signs equal? */
592  /* nope, see if numbers are equal? */
593  if (((leftLength == rightLength) && (leftExp == rightExp)) &&
594  !(memcmp(left->number, right->number, leftLength)) )
595  {
596 
597  return new_numberstring("0", 1); /* Yes, return Zero as result. */
598  }
599  operation = OT_MINUS; /* We are now doing a subtraction. */
600  }
601  else
602  { /* signs are equal, it is addition */
603  operation = OT_PLUS; /* We will now do a addition. */
604  }
605 
606  ResultSize = maxLength; /* size will be NUMERIC DIGITS + 1 */
607  result = (RexxNumberString *) new (ResultSize) RexxNumberString (ResultSize);
608 
609  result->sign = 0; /* make sure all values are zero */
610  result->exp=0; /* to start with ... */
611  result->length=0;
612 
613  /* LeftPtr points to end of number */
614  leftPtr = left->number + leftLength - 1;
615  /* RightPtr points to end of number */
616  rightPtr = right->number + rightLength - 1;
617  resultPtr = NULL; /* Initialize Result Ptr to 0; */
618 
619 
620  /* See if we need oto adjust the */
621  /* number with respect to current */
622  /* Digits setting. */
623  /* Compute the amount we may need to */
624  /* adjust for each number. Using the */
625  /* Adjusted exponents .... */
626  /* a value of 0 or less means we are */
627  /*OK. */
628  LadjustDigits = ((wholenumber_t)leftLength + aLeftExp) - (wholenumber_t)(maxLength);
629  RadjustDigits = ((wholenumber_t)rightLength + aRightExp) - (wholenumber_t)(maxLength);
630  /* Do we need to adjust any numbers? */
631  if (LadjustDigits > 0 || RadjustDigits >0 )
632  {
633  if (LadjustDigits >= RadjustDigits) /* yes, find which number needs to be*/
634  {
635  /* adjusted the most and assign the */
636  adjustDigits = LadjustDigits; /* adjustment value to adjustDigits. */
637  }
638  else
639  {
640  adjustDigits = RadjustDigits;
641  }
642  /* now we adjust the adjust exp */
643  /* and real length/exp of each no. */
644 
645 
646  if (aLeftExp)
647  { /* Was left exp larger than right */
648  if ((wholenumber_t)adjustDigits < aLeftExp)
649  { /* Do we need to adjust for more than*/
650  /* our adjusted exponent? */
651  aLeftExp -= adjustDigits; /* Yes, decrease adj exp */
652  /* Right number is now shorter */
653  rightPtr = rightPtr-adjustDigits;
654  rightExp += adjustDigits; /* Right exponent adjusted */
655  rightLength -= adjustDigits; /* update the length to reflect */
656  adjustDigits = 0; /* adjustment done. */
657  }
658  else
659  { /* decrease by adjusted exp value */
660  /* Right number is now shorter */
661  rightPtr = rightPtr-aLeftExp;
662  rightExp += aLeftExp; /* Right exponent adjusted */
663  rightLength -= adjustDigits; /* update the length to reflect */
664  adjustDigits -= aLeftExp; /* adjustment partially done. */
665  aLeftExp = 0; /* the adjusted exponent is now zero.*/
666  }
667  }
668  else if (aRightExp)
669  { /* Was right exp larger than left */
670  if ((wholenumber_t)adjustDigits < aRightExp)
671  { /* Do we adjust for more than */
672  /* our adjusted exponent? */
673  aRightExp -= adjustDigits; /* Yes, decrease adj exp */
674  /* Left number is now shorter */
675  leftPtr = leftPtr-adjustDigits;
676  leftExp += adjustDigits; /* Left exponent adjusted */
677  leftLength -= adjustDigits; /* update the length to reflect */
678  adjustDigits = 0; /* adjustment done. */
679  }
680  else
681  { /* decrease by adjusted exp value */
682  /* Right number is now shorter */
683  leftPtr = leftPtr-aRightExp;
684  leftExp += aRightExp; /* Right exponent adjusted */
685  leftLength -= adjustDigits; /* update the length to reflect */
686  adjustDigits -= aRightExp; /* adjustment partially done. */
687  aRightExp = 0; /* the adjusted exponent is now zero.*/
688  }
689  }
690 
691  if (adjustDigits)
692  { /* Is there still adjusting needed */
693  leftExp += adjustDigits; /* So adjust length and exp of each */
694  /* bumber by the remaining adjust */
695  leftPtr = leftPtr-adjustDigits;
696  rightExp += adjustDigits;
697  rightPtr = rightPtr - adjustDigits;
698  }
699  } /* Done with adjusting the numbers, */
700  if (NumberDigits <= FASTDIGITS) /* Get a buffer for the reuslt */
701  {
702  resultBuffer = resultBufFast;
703  }
704  else
705  {
706  resultBuffer = buffer_alloc(NumberDigits*2 + 1);
707  }
708 
709  /* Have Result Ptr point to end */
710  resultPtr = resultBuffer + NumberDigits*2;
711 
712  if (operation == OT_PLUS)
713  { /* Are we doing addition? */
714  carry = 0; /* no carry to start with. */
715 
716  /* we need check and see if there */
717  /* are values in the adjusted exps */
718  /* that is do we pretend there */
719  /* are extra zeros at the end */
720  /* of the numbers? */
721  result->sign = left->sign; /* we are doing addition, both signs */
722  /* are the same, assign use left for */
723  /* result. */
724  if (aLeftExp)
725  {
726  while (aLeftExp--)
727  { /* does left need zeros "added"? */
728  /* yes, move digits of right */
729  /* number into result */
730  /* xxxxxxx000 <- aLeftExp = 3 */
731  /* yyyyyyyyy <- aRightExp = 0 */
732  if (rightPtr >= right->number) /* Is there still data to move? */
733  {
734  *resultPtr-- = *rightPtr--; /* Yes, move in correct digit. */
735  }
736  else /* nope, */
737  {
738  *resultPtr-- = '\0'; /* nope, move in a zero. we remove */
739  }
740  /* leading zeros from orig number */
741  result->length++; /* Length is one greater. */
742  }
743  result->exp = rightExp; /* Right is smaller, assign to resul */
744  }
745  else if (aRightExp)
746  {
747  while (aRightExp--)
748  { /* does right need zeros "added"? */
749  /* yes, move digits of left */
750  /* number into result */
751  /* xxxxxxxxx <- aLeftExp = 0 */
752  /* yyyyyy00 <- aRightExp = 2 */
753 
754  if (leftPtr >= left->number) /* Is there still data to move? */
755  {
756  *resultPtr-- = *leftPtr--; /* Yes, move in correct digit. */
757  }
758  else /* nope, */
759  {
760  *resultPtr-- = '\0'; /* nope, move in a zero. */
761  }
762  result->length++; /* Result length is now one more. */
763  }
764  result->exp = leftExp; /* left is smaller, assign to result */
765  }
766  else
767  {
768  result->exp = leftExp; /* otherwise same exp. take left */
769  }
770 
771  while ( (leftPtr >= left->number) &&/* While we still have data to add. */
772  (rightPtr >= right->number) )
773  {
774  /* add the two current digits with a */
775  /* possibly carry bit, and update the*/
776  /* left and right ptr to point to */
777  /* next (actually previous) digit. */
778  addDigit = carry + (*leftPtr--) + *(rightPtr--);
779  if (addDigit >= 10)
780  { /* result greater than 10? we have a */
781  /* carry for our next addition. */
782  carry = 1; /* indicate carry. */
783  addDigit -= 10; /* subtract 10 from our result. */
784  }
785  else
786  { /* not bigger than 10. */
787  carry = 0; /* cancel any former carry */
788  }
789  *resultPtr-- = (char)addDigit; /* move result into the result */
790  result->length++; /* length of result is one more. */
791  } /* go back and do next set of digits */
792 
793  /* One of the numbers is finished, */
794  /* check the other. */
795 
796  while (leftPtr >= left->number)
797  { /* While still digits in the */
798  /* left number. */
799  addDigit = carry + (*leftPtr--); /* add in any carry, and move to */
800  /* next digit to add. */
801  if (addDigit >= 10)
802  { /* do we still have a carry */
803  carry = 1; /* yes, indicate carry. */
804  addDigit -= 10; /* subtract 10 from our result. */
805  }
806  else
807  { /* not bigger than 10. */
808  carry = 0; /* make sure we cancel former carry */
809  }
810  *resultPtr-- = (char)addDigit; /* move result into the result */
811  result->length++; /* length of result is one more. */
812  } /* all done with left number. */
813 
814  while (rightPtr >= right->number)
815  { /* While there is still digits in */
816  /* right number. */
817  addDigit = carry + (*rightPtr--); /* add in any carry, and move to the */
818  /* next digit to add. */
819  if (addDigit >= 10)
820  { /* do we still have a carry */
821  carry = 1; /* indicate carry. */
822  addDigit -= 10; /* subtract 10 from our result. */
823  }
824  else
825  { /* not bigger than 10. */
826  carry = 0; /* make sure we cancel former carry */
827  }
828  *resultPtr-- = (char)addDigit; /* move result into the result */
829  result->length++; /* length of result is one more. */
830  } /* all done with left number. */
831 
832  if (carry)
833  { /* Do we still have a carry over? */
834  result->length++; /* yes, number is now one more */
835  *resultPtr-- = 1; /* set the high digit to 1. */
836  }
837  } /* end of addition. */
838 
839  else
840  { /* we are doing subtraction. */
841 
842  /* is left number bigger than right */
843  if ((aLeftExp + leftLength)>(aRightExp + rightLength))
844  {
845  /* yes, subtract right from left */
846  subtractNumbers(left, leftPtr, aLeftExp, right, rightPtr, aRightExp, result, &resultPtr);
847  /* result exp is the adjusted exp of */
848  /* smaller number. */
849  if (aLeftExp) /* if adjusted left exp has a value */
850  {
851  result->exp = rightExp; /* the the right exp was smaller */
852  }
853  else
854  {
855  result->exp = leftExp; /* otherwise left was smaller/equal */
856  }
857 
858  result->sign = left->sign; /* result sign is that of left. */
859  }
860  /* is right number bigger than left */
861  else if ((aLeftExp + leftLength)<(aRightExp + rightLength))
862  {
863  /* yes, subtract left from right */
864  subtractNumbers(right, rightPtr, aRightExp, left, leftPtr, aLeftExp, result, &resultPtr);
865  /* result exp is adjusted exp of the */
866  /* smaller number. */
867  if (aLeftExp) /* if adjusted left exp has a value */
868  {
869  result->exp = rightExp; /* the the right exp was smaller */
870  }
871  else
872  {
873  result->exp = leftExp; /* otherwise left was smaller/equal */
874  }
875 
876  result->sign = right_sign; /* result sign is that of right. */
877  }
878 
879  /* here both numbers have same */
880  /* adjusted lexponent + length */
881  /* so see which number is longer and */
882  /* each number for length of smaller.*/
883  /* if they compare equal the result */
884  /* is zero */
885  else if (rightLength < leftLength)
886  {/* Does right number have a smaller */
887  /* length. */
888 
889  /* Yes, compare the digits.... */
890  /* and see if right is larger. */
891  if ((rc = memcmp(right->number, left->number, rightLength)) > 0)
892  {
893  /* yes, subtract left from right */
894  subtractNumbers(right, rightPtr, aRightExp, left, leftPtr, aLeftExp, result, &resultPtr);
895  result->sign = right_sign; /* result sign is that of right. */
896  }
897  else
898  {
899  /* no, subtract right from left */
900  subtractNumbers(left, leftPtr, aLeftExp, right, rightPtr, aRightExp, result, &resultPtr);
901  result->sign = left->sign; /* result sign is that of left. */
902  }
903  result->exp = leftExp; /* result exp is that of the longer */
904  /* number (smaller Exp.) which is the*/
905  /* left number in this case. */
906  }
907  else
908  { /* left length is smaller or equal to*/
909  /* the length of right. */
910  /* see if left number is larger */
911  if ((rc = memcmp(left->number, right->number, leftLength)) > 0)
912  {
913  /* yes, subtract right from left */
914  subtractNumbers(left, leftPtr, aLeftExp, right, rightPtr, aRightExp, result, &resultPtr);
915  result->exp = rightExp; /* result exp is that of the longer */
916  /* number (smaller Exp.) which is */
917  /* right number in this case. */
918 
919  result->sign = left->sign; /* result sign is that of left. */
920  }
921  else if (rc)
922  { /* is the right number larger? */
923  /* no, subtract left from right */
924  subtractNumbers(right, rightPtr, aRightExp, left, leftPtr, aLeftExp, result, &resultPtr);
925  result->exp = rightExp; /* result exp is that of the longer */
926  /* number (smaller Exp.) which is the*/
927  /* right number in this case. */
928  result->sign = right_sign; /* result sign is that of right. */
929  }
930  else
931  { /* numbers compared are equal. */
932  if (leftLength < rightLength)
933  { /* does left have fewer digits? */
934  /* Yes, then left is actuall smaller */
935  /* so subtract left from right */
936  subtractNumbers(right, rightPtr, aRightExp, left, leftPtr, aLeftExp, result, &resultPtr);
937  result->exp = rightExp; /* result exp is that of the longer */
938  /* number (smaller Exp.) which is */
939  /* left number in this case. */
940  result->sign = right_sign; /* result sign is that of right. */
941  }
942  else
943  { /* Lengths are also eqaul, so numbers*/
944  /* are identical. */
945  result->sign=0; /* number equal, return 0 */
946  result->exp = 0;
947  result->length = 1;
948  result->number[0] = '0';
949  }
950  }
951  }
952  } /* End of subtraction. */
953 
954  /* pointer resultPtr always points */
955  /* to next position to add a digit */
956  /* thereofre we will bump the pointer*/
957  /* 1st before doing any cleanup */
958  /* we end up pointing to the most sig*/
959  /* digit on exit of loop instead of */
960  /* the 1st digit. */
961 
962  /*make sure result end up with */
963  /* correct precision. */
964  result->adjustPrecision(++resultPtr, NumberDigits);
965  return result; /* all done, return the result */
966 
967 }
968 
970  RexxNumberString *larger, /* larger numberstring object */
971  const char *largerPtr, /* pointer to last digit in larger */
972  wholenumber_t aLargerExp, /* adjusted exponent of larger */
973  RexxNumberString *smaller, /* smaller numberstring object */
974  const char *smallerPtr, /* pointer to last digit in smaller */
975  wholenumber_t aSmallerExp, /* adjusted exponent of smaller */
976  RexxNumberString *result, /* result numberstring object */
977  char **presultPtr) /* last number in result */
978 /*********************************************************************/
979 /* Function: Subtract two numbers. The second number is subtracted */
980 /* from the first. The absolute value of the 1st number */
981 /* must be larger than the absolute value of the second. */
982 /*********************************************************************/
983 {
984  int borrow, subDigit;
985  char *resultPtr;
986 
987  resultPtr = *presultPtr; /* since we need to update value of */
988  /* resultPtr and return value to */
989  /* caller, we are passed a pointer */
990  /* pointer, we'll just use Ptr to */
991  /* data. (avoid reference problems) */
992  /* we will update this pointer value */
993  /* before exiting, so the Ptr */
994  /* is correct in caller. */
995  borrow = 0; /* no carry to start with. */
996 
997  /* 1st we need to make both adjusted */
998  /* exponents zero. values are either*/
999  /* positive or zero on entry. */
1000  /* one of the adjusted exponents will*/
1001  /* always be zero on entry. */
1002  while (aLargerExp--)
1003  { /* if larger number had a value for */
1004  /* for adjusted exponent that means */
1005  /* that smaller number had a smaller */
1006  /* exponent (less significant digit */
1007  /* so we pretend to add extra zeros */
1008  /* to the larger number and do the */
1009  /* subtraction for required number */
1010  /* of digits, (aLargerExp). */
1011  /* xxxxx00 */
1012  /* yyyyyy */
1013 
1014  if (smallerPtr >= smaller->number) /* Is there still data to subtract */
1015  {
1016  subDigit = *smallerPtr--; /* Yes, set value for subtraction */
1017  }
1018  else /* nope, */
1019  {
1020  subDigit = '\0'; /* nope, use a Zero for subtraction. */
1021  }
1022 
1023  /* subtract 10 from smaller number, */
1024  /* any borrow. */
1025  /* and point to next digit. */
1026  subDigit = borrow + 10 - subDigit;
1027  if (subDigit == 10)
1028  { /* was result 10, this can only occur*/
1029  /* the bottom digit was a zero and we*/
1030  /* didn't borrow anyting. */
1031  subDigit -= 10; /* Yes, result will be zero and */
1032  borrow = 0; /* no borrow. */
1033  }
1034  else
1035  {
1036  borrow = -1; /* nope, result digit ok, and we */
1037  }
1038  /* need to borrow. */
1039  *resultPtr-- = (char)subDigit; /* place this digit in result number */
1040  result->length++; /* length of result is now one more. */
1041  }
1042 
1043  while (aSmallerExp--)
1044  { /* if smaller number had a value for */
1045  /* for adjusted exponent that means */
1046  /* that larger number had a smaller */
1047  /* exponent (more significant digit */
1048  /* so we pretend to add extra zeros */
1049  /* to smaller number and do the */
1050  /* subtraction for required number */
1051  /* of digits, (aSmallerExp). */
1052  /* xxxxxxx */
1053  /* yyyy00 */
1054 
1055  /* here we just move the the digits */
1056  /* from larger into result. */
1057  /* and point to next digit. */
1058 
1059  if (largerPtr >= larger->number) /* Is there still data to move? */
1060  {
1061  *resultPtr-- = *largerPtr--; /* Yes, move in correct digit. */
1062  }
1063  else /* nope, */
1064  {
1065  *resultPtr-- = '\0'; /* nope, move in a zero. we remove */
1066  }
1067  /* leading zeros from orig number */
1068  result->length++; /* length of result is now one more. */
1069  }
1070 
1071  /* Now we are ready to do subtract */
1072  /* of our digits. */
1073  /* While still have data to subtract */
1074  while (smallerPtr >= smaller->number)
1075  {
1076  /* Sub two current digits with a */
1077  /* possibly borrow bit, and update */
1078  /* larger and smaller pointer to */
1079  /* to next (actually previous) digit */
1080  subDigit = borrow + (*largerPtr--) - *(smallerPtr--);
1081  if (subDigit < 0 )
1082  { /* result less than 0, Do we need to */
1083  /* borrow for next subtraction */
1084  borrow = -1; /* yes, indicate borrow. */
1085  subDigit += 10; /* add 10 to result from borrow. */
1086  }
1087  else
1088  { /* not less than 0 */
1089  borrow = 0; /* make sure we cancel former borrow */
1090  }
1091  *resultPtr-- = (char)subDigit; /* move result into result object. */
1092  result->length++; /* length of result is one more. */
1093  } /* go back and do next set of digits */
1094 
1095  /* One number is finished, need */
1096  /* to check the other. */
1097 
1098  while (largerPtr >= larger->number)
1099  {/* While still digits in the larger */
1100  subDigit = borrow + (*largerPtr--);/* sub any borrow, and move to the */
1101  /* next digit to subtract. */
1102  if (subDigit < 0 )
1103  { /* do we still need to borrow? */
1104  borrow = -1; /* yes, indicate borrow */
1105  subDigit += 10; /* add 10 to result for borrow. */
1106  }
1107  else
1108  { /* not bigger than 10. */
1109  borrow = 0; /* make sure we cancel former carry */
1110  }
1111  *resultPtr-- = (char)subDigit; /* move result into result object. */
1112  result->length++; /* length of result is one more. */
1113  } /* all done with larger number. */
1114 
1115  *presultPtr = resultPtr; /* update result PTR for our return */
1116  return;
1117 }
1118 
1120  int Digit, /* digit to add */
1121  char *Value, /* number to add */
1122  char *HighDigit ) /* highest digit location */
1123 /*********************************************************************/
1124 /* Function: Adds a base ten digit to string number in */
1125 /* base 16 (used by the d2x and d2c functions) */
1126 /*********************************************************************/
1127 {
1128  while (Digit)
1129  { /* while something to add */
1130  Digit += *Value; /* add in current number */
1131  if (Digit > 15)
1132  { /* carry? */
1133  Digit -= 16; /* reduce digit */
1134  *Value-- = (char)Digit; /* set digit and step pointer */
1135  Digit = 1; /* just a carry digit now */
1136  }
1137  else
1138  {
1139  *Value-- = (char)Digit; /* set the digit */
1140  Digit = 0; /* no more carry */
1141  }
1142  }
1143  if (Value < HighDigit) /* new high water mark? */
1144  {
1145  return Value; /* return high location */
1146  }
1147  else
1148  {
1149  return HighDigit; /* return the old one */
1150  }
1151 }
1152 
1154  char * Accum, /* number to multiply */
1155  char * HighDigit ) /* current high water mark */
1156 /*********************************************************************/
1157 /* Function: multiplies a base 16 number by 10, placing */
1158 /* the result in the same buffer. */
1159 /*********************************************************************/
1160 {
1161  int Carry; /* multiplication carry */
1162  unsigned int Digit; /* current digit */
1163  char * OutPtr; /* output pointer */
1164 
1165  OutPtr = Accum; /* point to first digit */
1166  Carry = 0; /* no carry yet */
1167  while (OutPtr > HighDigit)
1168  { /* while more digits */
1169  /* multiply digit by 10 */
1170  Digit = (unsigned int )((*OutPtr * 10) + Carry);
1171  if (Digit > 15)
1172  { /* carry? */
1173  Carry = (int)(Digit / 16); /* get carry value */
1174  Digit &= (unsigned int )0x0000000f; /* keep just lower nibble */
1175  }
1176  else /* no carry here */
1177  {
1178  Carry = 0; /* no carry */
1179  }
1180  *OutPtr-- = (char)Digit; /* set the digit */
1181  }
1182  if (Carry) /* carried out? */
1183  {
1184  *OutPtr-- = (char)Carry; /* set the carry pointer */
1185  }
1186  return OutPtr; /* return new high water mark */
1187 }
1188 
1190  int Digit, /* digit to add */
1191  char *Accum, /* number to add */
1192  char *HighDigit ) /* highest digit location */
1193 /*********************************************************************/
1194 /* Function: Adds a base sixteen digit to a string number */
1195 /* base 10 (used by the d2x and d2c functions) */
1196 /*********************************************************************/
1197 {
1198  int Carry; /* carry number */
1199 
1200  Carry = 0; /* no carry yet */
1201  while (Digit || Carry)
1202  { /* while something to add */
1203  Digit += *Accum + Carry; /* add in current number */
1204  if (Digit > 9)
1205  { /* carry? */
1206  Carry = Digit / 10; /* get the carry out */
1207  Digit %= 10; /* reduce digit */
1208  *Accum-- = (char)Digit; /* set digit and step pointer */
1209  }
1210  else
1211  {
1212  *Accum-- = (char)Digit; /* set the digit */
1213  Carry = 0; /* no more carry */
1214  }
1215  Digit = 0; /* no addition after first */
1216  }
1217  if (Accum < HighDigit) /* new high water mark? */
1218  {
1219  return Accum; /* return high location */
1220  }
1221  else
1222  {
1223  return HighDigit; /* return the old one */
1224  }
1225 }
1226 
1228  char * Accum, /* number to multiply */
1229  char * HighDigit ) /* current high water mark */
1230 
1231 /*********************************************************************/
1232 /* Function: multiplies a base 16 number by 10, placing */
1233 /* the number in a different buffer. */
1234 /*********************************************************************/
1235 {
1236  char * OutPtr; /* addition pointer */
1237  int Carry; /* multiplication carry */
1238  unsigned int Digit; /* current digit */
1239 
1240  OutPtr = Accum; /* point to output buffer */
1241  Carry = 0; /* no carry yet */
1242 
1243  while (OutPtr > HighDigit)
1244  { /* while more digits */
1245  /* multiply digit by 16 */
1246  Digit = (unsigned int )((*OutPtr * 16) + Carry);
1247  if (Digit > 9)
1248  { /* carry? */
1249  Carry = (int)(Digit / 10); /* get carry value */
1250  Digit %= 10; /* get the digit value */
1251  }
1252  else /* no carry here */
1253  {
1254  Carry = 0; /* no carry */
1255  }
1256  *OutPtr-- = (char)Digit; /* set the digit */
1257  }
1258  while (Carry)
1259  { /* carried out? */
1260  Digit = Carry % 10; /* get first carry digit */
1261  Carry = Carry / 10; /* get the next digit */
1262  *OutPtr-- = (char)Digit; /* set the digit */
1263  }
1264  return OutPtr; /* return new high water mark */
1265 }
RexxNumberStringBase::length
size_t length
Definition: NumberStringClass.hpp:90
reportCondition
void reportCondition(RexxString *condition, RexxString *description)
Definition: ActivityManager.hpp:132
RexxNumberString::addToBaseSixteen
static char * addToBaseSixteen(int, char *, char *)
Definition: NumberStringMath.cpp:1119
Error_Incorrect_call_noarg
#define Error_Incorrect_call_noarg
Definition: RexxErrorCodes.h:331
Error_Incorrect_method_number
#define Error_Incorrect_method_number
Definition: RexxErrorCodes.h:458
RexxNumberString::subtractNumbers
static void subtractNumbers(RexxNumberString *larger, const char *largerPtr, wholenumber_t aLargerExp, RexxNumberString *smaller, const char *smallerPtr, wholenumber_t aSmallerExp, RexxNumberString *result, char **resultPtr)
Definition: NumberStringMath.cpp:969
RexxNumberString::prepareOperatorNumber
RexxNumberString * prepareOperatorNumber(size_t, size_t, bool)
Definition: NumberStringMath.cpp:432
RexxNumberString::maxMin
RexxNumberString * maxMin(RexxObject **, size_t, unsigned int)
Definition: NumberStringMath.cpp:59
RexxNumberString::isLessThan
RexxInteger * isLessThan(RexxObject *)
Definition: NumberStringClass.cpp:2945
RexxNumberString::setupNumber
void setupNumber()
Definition: NumberStringClass.hpp:191
RexxNumberString::highBits
static size_t highBits(size_t)
Definition: NumberStringMath.cpp:249
OT_MAX
#define OT_MAX
Definition: NumberStringMath.hpp:56
ActivityManager.hpp
RexxNumberString::adjustPrecision
void adjustPrecision()
Definition: NumberStringMath.cpp:211
RexxActivationBase::fuzz
virtual size_t fuzz()
Definition: ObjectClass.hpp:580
FASTDIGITS
#define FASTDIGITS
Definition: NumberStringMath.hpp:77
new_numberstring
RexxNumberString * new_numberstring(const char *s, stringsize_t l)
Definition: NumberStringClass.hpp:274
RexxNumberStringBase::NumDigits
size_t NumDigits
Definition: NumberStringClass.hpp:87
Numerics::MIN_EXPONENT
static const wholenumber_t MIN_EXPONENT
Definition: Numerics.hpp:65
reportException
void reportException(wholenumber_t error)
Definition: ActivityManager.hpp:136
OT_MINUS
#define OT_MINUS
Definition: NumberStringMath.hpp:50
TheTrueObject
#define TheTrueObject
Definition: RexxCore.h:185
Error_Overflow_expunderflow
#define Error_Overflow_expunderflow
Definition: RexxErrorCodes.h:379
RexxActivationBase
Definition: ObjectClass.hpp:574
RexxNumberString::setNumericSettings
void setNumericSettings(size_t digits, bool form)
Definition: NumberStringClass.hpp:182
RexxNumberString::RexxNumberString
RexxNumberString(size_t)
Definition: NumberStringClass.cpp:85
RexxActivity::getTopStackFrame
RexxActivationBase * getTopStackFrame()
Definition: RexxActivity.hpp:281
RexxNumberStringBase::adjustNumber
char * adjustNumber(char *, char *, size_t, size_t)
Definition: NumberStringMath.cpp:274
OREF_NULL
#define OREF_NULL
Definition: RexxCore.h:60
ArrayClass.hpp
ProtectedObject.hpp
RexxNumberStringBase::stripLeadingZeros
char * stripLeadingZeros(char *)
Definition: NumberStringMath.cpp:308
number_form
bool number_form()
Definition: Numerics.hpp:149
NumberStringClass.hpp
RexxNumberString::addSub
RexxNumberString * addSub(RexxNumberString *, unsigned int, size_t)
Definition: NumberStringMath.cpp:464
ProtectedObject
Definition: ProtectedObject.hpp:46
StringClass.hpp
RexxNumberString::isGreaterThan
RexxInteger * isGreaterThan(RexxObject *)
Definition: NumberStringClass.cpp:2933
NumberStringMath.hpp
RexxNumberString::addToBaseTen
static char * addToBaseTen(int, char *, char *)
Definition: NumberStringMath.cpp:1189
Numerics::DEFAULT_DIGITS
static const size_t DEFAULT_DIGITS
Definition: Numerics.hpp:66
HIBIT
#define HIBIT
Definition: NumberStringMath.hpp:71
buffer_alloc
#define buffer_alloc(s)
Definition: NumberStringMath.hpp:75
RexxNumberString::multiplyBaseSixteen
static char * multiplyBaseSixteen(char *, char *)
Definition: NumberStringMath.cpp:1153
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
CHAR_ORXMAX
char CHAR_ORXMAX[]
RexxNumberString::multiplyBaseTen
static char * multiplyBaseTen(char *, char *)
Definition: NumberStringMath.cpp:1227
RexxNumberString::setZero
void setZero()
Definition: NumberStringClass.hpp:234
RexxString::length
size_t length
Definition: StringClass.hpp:487
RexxNumberStringBase::mathRound
void mathRound(char *)
Definition: NumberStringMath.cpp:153
ActivityManager::currentActivity
static RexxActivity *volatile currentActivity
Definition: ActivityManager.hpp:95
RexxNumberString::adjustPrecision
void adjustPrecision(char *, size_t)
Definition: NumberStringMath.cpp:324
OT_PLUS
#define OT_PLUS
Definition: NumberStringMath.hpp:49
RexxObject::numberString
RexxNumberString * numberString()
Definition: ObjectClass.cpp:1018
RexxActivity.hpp
RexxActivationBase::digits
virtual size_t digits()
Definition: ObjectClass.hpp:579
Error_Overflow_expoverflow
#define Error_Overflow_expoverflow
Definition: RexxErrorCodes.h:378
RexxNumberString::clone
RexxNumberString * clone()
Definition: NumberStringClass.cpp:114
RexxNumberString::prepareNumber
RexxNumberString * prepareNumber(size_t, bool)
Definition: NumberStringMath.cpp:388
RexxCore.h
RexxActivationBase::setFuzz
virtual void setFuzz(size_t)
Definition: ObjectClass.hpp:586
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
RexxInteger
Definition: IntegerClass.hpp:56
ROUND
#define ROUND
Definition: NumberStringMath.hpp:67
BufferClass.hpp
RexxObject
Definition: ObjectClass.hpp:311
RexxString
Definition: StringClass.hpp:119
CHAR_ORXMIN
char CHAR_ORXMIN[]