Example #1
0
static void
decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn)
{
  decContext set;
  decContextDefault (&set, DEC_INIT_DECIMAL128);
  set.traps = 0;

  switch (r->cl)
    {
    case rvc_zero:
      decNumberZero (dn);
      break;
    case rvc_inf:
      decNumberFromString (dn, (char *)"Infinity", &set);
      break;
    case rvc_nan:
      if (r->signalling)
        decNumberFromString (dn, (char *)"snan", &set);
      else
        decNumberFromString (dn, (char *)"nan", &set);
      break;
    case rvc_normal:
      gcc_assert (r->decimal);
      decimal128ToNumber ((decimal128 *) r->sig, dn);
      break;
    default:
      gcc_unreachable ();
    }

  /* Fix up sign bit.  */
  if (r->sign != decNumberIsNegative (dn))
    dn->bits ^= DECNEG;
}
Example #2
0
int main(int argc, char *argv[]) {
  { // excerpt for User's Guide starts here--------------------------|
  decNumber one, mtwo, hundred;                   // constants
  decNumber start, rate, years;                   // parameters
  decNumber total;                                // result
  decContext set;                                 // working context

  uint8_t startpack[]={0x01, 0x00, 0x00, 0x0C};   // investment=100000
  int32_t startscale=0;
  uint8_t ratepack[]={0x06, 0x5C};                // rate=6.5%
  int32_t ratescale=1;
  uint8_t yearspack[]={0x02, 0x0C};               // years=20
  int32_t yearsscale=0;
  uint8_t respack[16];                            // result, packed
  int32_t resscale;                               // ..
  char  hexes[49];                                // for packed->hex
  int   i;                                        // counter

  if (argc<0) printf("%s", argv[1]);              // noop for warning

  decContextDefault(&set, DEC_INIT_BASE);         // initialize
  set.traps=0;                                    // no traps
  set.digits=25;                                  // precision 25
  decNumberFromString(&one,       "1", &set);     // set constants
  decNumberFromString(&mtwo,     "-2", &set);
  decNumberFromString(&hundred, "100", &set);

  decPackedToNumber(startpack, sizeof(startpack), &startscale, &start);
  decPackedToNumber(ratepack,  sizeof(ratepack),  &ratescale,  &rate);
  decPackedToNumber(yearspack, sizeof(yearspack), &yearsscale, &years);

  decNumberDivide(&rate, &rate, &hundred, &set);  // rate=rate/100
  decNumberAdd(&rate, &rate, &one, &set);         // rate=rate+1
  decNumberPower(&rate, &rate, &years, &set);     // rate=rate^years
  decNumberMultiply(&total, &rate, &start, &set); // total=rate*start
  decNumberRescale(&total, &total, &mtwo, &set);  // two digits please

  decPackedFromNumber(respack, sizeof(respack), &resscale, &total);

  // lay out the total as sixteen hexadecimal pairs
  for (i=0; i<16; i++) {
    sprintf(&hexes[i*3], "%02x ", respack[i]);
    }
  printf("Result: %s (scale=%ld)\n", hexes, (long int)resscale);

  } //---------------------------------------------------------------|
  return 0;
  } // main
Example #3
0
DecimalDecNumber &DecimalDecNumber::operator=(double rhs)
{
    char buffer[512] = {0}; // Stack allocated string
    snprintf(buffer, 511, "%0.15lg", rhs);
    decNumberFromString(&m_value, buffer, &m_context);
    return *this;
}
Example #4
0
File: dfp.c Project: AHelper/gcc
static void
decimal_to_decnumber (const REAL_VALUE_TYPE *r, decNumber *dn)
{
  decContext set;
  decContextDefault (&set, DEC_INIT_DECIMAL128);
  set.traps = 0;

  switch (r->cl)
    {
    case rvc_zero:
      decNumberZero (dn);
      break;
    case rvc_inf:
      decNumberFromString (dn, "Infinity", &set);
      break;
    case rvc_nan:
      if (r->signalling)
        decNumberFromString (dn, "snan", &set);
      else
        decNumberFromString (dn, "nan", &set);
      break;
    case rvc_normal:
      if (!r->decimal)
	{
	  /* dconst{1,2,m1,half} are used in various places in
	     the middle-end and optimizers, allow them here
	     as an exception by converting them to decimal.  */
	  if (memcmp (r, &dconst1, sizeof (*r)) == 0)
	    {
	      decNumberFromString (dn, "1", &set);
	      break;
	    }
	  if (memcmp (r, &dconst2, sizeof (*r)) == 0)
	    {
	      decNumberFromString (dn, "2", &set);
	      break;
	    }
	  if (memcmp (r, &dconstm1, sizeof (*r)) == 0)
	    {
	      decNumberFromString (dn, "-1", &set);
	      break;
	    }
	  if (memcmp (r, &dconsthalf, sizeof (*r)) == 0)
	    {
	      decNumberFromString (dn, "0.5", &set);
	      break;
	    }
	  gcc_unreachable ();
	}
      decimal128ToNumber ((const decimal128 *) r->sig, dn);
      break;
    default:
      gcc_unreachable ();
    }

  /* Fix up sign bit.  */
  if (r->sign != decNumberIsNegative (dn))
    dn->bits ^= DECNEG;
}
Example #5
0
INT_TYPE
DFP_TO_INT (DFP_C_TYPE x)
{
  /* decNumber's decimal* types have the same format as C's _Decimal*
     types, but they have different calling conventions.  */

  IEEE_TYPE s;
  char buf[BUFMAX];
  char *pos;
  decNumber qval, n1, n2;
  decContext context;

  decContextDefault (&context, CONTEXT_INIT);
  /* Need non-default rounding mode here.  */
  context.round = DEC_ROUND_DOWN;

  HOST_TO_IEEE (x, &s);
  TO_INTERNAL (&s, &n1);
  /* Rescale if the exponent is less than zero.  */
  decNumberToIntegralValue (&n2, &n1, &context);
  /* Get a value to use for the quantize call.  */
  decNumberFromString (&qval, (char *) "1.0", &context);
  /* Force the exponent to zero.  */
  decNumberQuantize (&n1, &n2, &qval, &context);
  /* This is based on text in N1107 section 5.1; it might turn out to be
     undefined behavior instead.  */
  if (context.status & DEC_Invalid_operation)
    {
#if defined (L_sd_to_si) || defined (L_dd_to_si) || defined (L_td_to_si)
      if (decNumberIsNegative(&n2))
        return INT_MIN;
      else
        return INT_MAX;
#elif defined (L_sd_to_di) || defined (L_dd_to_di) || defined (L_td_to_di)
      if (decNumberIsNegative(&n2))
        /* Find a defined constant that will work here.  */
        return (-9223372036854775807LL - 1LL);
      else
        /* Find a defined constant that will work here.  */
        return 9223372036854775807LL;
#elif defined (L_sd_to_usi) || defined (L_dd_to_usi) || defined (L_td_to_usi)
      return UINT_MAX;
#elif defined (L_sd_to_udi) || defined (L_dd_to_udi) || defined (L_td_to_udi)
        /* Find a defined constant that will work here.  */
      return 18446744073709551615ULL;
#endif
    }
  /* Get a string, which at this point will not include an exponent.  */
  decNumberToString (&n1, buf);
  /* Ignore the fractional part.  */
  pos = strchr (buf, '.');
  if (pos)
    *pos = 0;
  /* Use a C library function to convert to the integral type.  */
  return STR_TO_INT (buf, NULL, 10);
}
Example #6
0
DecimalDecNumber::DecimalDecNumber(double rhs)
{
   decContextDefault(&m_context, DEC_INIT_BASE); // initialize
   m_context.traps = 0;                     // no traps, thank you
   m_context.digits = DECNUMDIGITS;         // set precision

   char buffer[512] = {0}; // Stack allocated string
   snprintf(buffer, 511, "%0.15lg", rhs);
   decNumberFromString(&m_value, buffer, &m_context);
}
Example #7
0
void
decimal_real_from_string (REAL_VALUE_TYPE *r, const char *s)
{
  decNumber dn;
  decContext set;
  decContextDefault (&set, DEC_INIT_DECIMAL128);
  set.traps = 0;

  decNumberFromString (&dn, (char *) s, &set);

  /* It would be more efficient to store directly in decNumber format,
     but that is impractical from current data structure size.
     Encoding as a decimal128 is much more compact.  */
  decimal_from_decnumber (r, &dn, &set);
}
Example #8
0
/* ------------------------------------------------------------------ */
decimal64 *
decimal64FromString (decimal64 * result, const char *string, decContext * set)
{
  decContext dc;
  decNumber dn;

  decContextDefault (&dc, DEC_INIT_DECIMAL64);
  dc.round = set->round;

  decNumberFromString (&dn, string, &dc);
  decimal64FromNumber (result, &dn, &dc);
  if (dc.status != 0)
    decContextSetStatus (set, dc.status);
  return result;
}
Example #9
0
int main(int argc, char *argv[]) {
  decNumber a, b;                  // working numbers
  decContext set;                  // working context
  char string[DECNUMDIGITS+14];    // conversion buffer

  decContextTestEndian(0);         // warn if DECLITEND is wrong

  if (argc<3) {                    // not enough words
    printf("Please supply two numbers to add.\n");
    return 1;
    }
  decContextDefault(&set, DEC_INIT_BASE); // initialize
  set.traps=0;                     // no traps, thank you
  set.digits=DECNUMDIGITS;         // set precision

  decNumberFromString(&a, argv[1], &set);
  decNumberFromString(&b, argv[2], &set);

  decNumberAdd(&a, &a, &b, &set);            // a=a+b
  decNumberToString(&a, string);

  printf("%s + %s => %s\n", argv[1], argv[2], string);
  return 0;
  } // main
Example #10
0
DecimalDecNumber::DecimalDecNumber(uint64 rhs)
{
   decContextDefault(&m_context, DEC_INIT_BASE); // initialize
   m_context.traps = 0;                     // no traps, thank you
   m_context.digits = DECNUMDIGITS;         // set precision

   if (rhs <= std::numeric_limits<uint>::max())
   {
      decNumberFromUInt32(&m_value, static_cast<uint>(rhs));
   }
   else
   {
      char buffer[64];
      uint64_to_string(rhs, buffer);
      decNumberFromString(&m_value, buffer, &m_context);
   }
}
Example #11
0
decimal32 *
decimal32FromString (decimal32 *result, const char *string,
		      decContext *set)
{
  decContext dc;		/* work */
  decNumber dn;			/* .. */

  decContextDefault (&dc, DEC_INIT_DECIMAL32);	/* no traps, please */
  dc.round = set->round;	/* use supplied rounding */

  decNumberFromString (&dn, string, &dc);	/* will round if needed */
  decimal32FromNumber (result, &dn, &dc);
  if (dc.status != 0)
    {				/* something happened */
      decContextSetStatus (set, dc.status);	/* .. pass it on */
    }
  return result;
}
Example #12
0
static VALUE num_initialize(int argc, VALUE *argv, VALUE self) {
  decNumber *self_ptr;
  decContext *context_ptr;
  VALUE from, r_str, context, digits;

  rb_scan_args( argc, argv, "02", &from, &digits );
  context = rb_funcall( cDecContext, rb_intern("new"), 1, digits );
  rb_iv_set( self, "@context", context );
  Data_Get_Struct(context, decContext, context_ptr);
  Data_Get_Struct(self, decNumber, self_ptr);

  if ( NIL_P(from) ) {
    /*    decNumberFromString(dec_num_ptr, "0", &dec_context); */
  } else {
    r_str = rb_funcall(from, rb_intern("to_s"), 0);
    decNumberFromString(self_ptr, StringValuePtr( r_str ), context_ptr);
  }
  return self;
}
Example #13
0
/// Convert the string presented into a form acceptable to the dec number class
/// @throws exception when the format causes a problem in the number conversion.
///
void DecimalDecNumber::setValue(const char *rhs)
{
   decNumberFromString(&m_value, rhs, &m_context);

   const unsigned int state = decContextGetStatus(&m_context);
   if (state)
   {
      // See decContext.h for definition of DEC_Errors and DEC_Information
      if (state & DEC_Errors)
      {
         // GLCRIT(DEC_NUMBER, "decNumberFromString conversion from [%s] generated error status [%d:%s]",
         //        rhs, state, decContextStatusToString(&m_context));
         // FTHROW(InvalidArgumentException, "Attempt to create decimal from invalid string: [%s]", rhs);
         throw("Attempt to create decimal from invalid string");
      }

      // GLDBUG(DEC_NUMBER, "decNumberFromString conversion from [%s] generated info status [%d:%s]",
      //        rhs, state, decContextStatusToString(&m_context));
      decContextClearStatus(&m_context, 0U);
   }
}
Example #14
0
int main(int argc, char *argv[]) {
  decQuad a;                       // working decQuad
  decNumber numa, numb;            // working decNumbers
  decContext set;                  // working context
  char string[DECQUAD_String];     // number->string buffer

  if (argc<3) {                    // not enough words
    printf("Please supply two numbers for power(2*a, b).\n");
    return 1;
    }
  decContextDefault(&set, DEC_INIT_DECQUAD); // initialize

  decQuadFromString(&a, argv[1], &set);      // get a
  decQuadAdd(&a, &a, &a, &set);              // double a
  decQuadToNumber(&a, &numa);                // convert to decNumber
  decNumberFromString(&numb, argv[2], &set);
  decNumberPower(&numa, &numa, &numb, &set); // numa=numa**numb
  decQuadFromNumber(&a, &numa, &set);        // back via a Quad
  decQuadToString(&a, string);               // ..

  printf("power(2*%s, %s) => %s\n", argv[1], argv[2], string);
  return 0;
  } // main
Example #15
0
/* decNumber doesn't provide support for conversions to 64-bit integer
   types, so do it the hard way.  */
INT_TYPE
DFP_TO_INT (DFP_C_TYPE x)
{
  /* decNumber's decimal* types have the same format as C's _Decimal*
     types, but they have different calling conventions.  */

  /* TODO: Decimal float to integer conversions should raise FE_INVALID
     if the result value does not fit into the result type.  */

  IEEE_TYPE s;
  char buf[BUFMAX];
  char *pos;
  decNumber qval, n1, n2;
  decContext context;

  /* Use a large context to avoid losing precision.  */
  decContextDefault (&context, DEC_INIT_DECIMAL128);
  /* Need non-default rounding mode here.  */
  context.round = DEC_ROUND_DOWN;

  HOST_TO_IEEE (x, &s);
  TO_INTERNAL (&s, &n1);
  /* Rescale if the exponent is less than zero.  */
  decNumberToIntegralValue (&n2, &n1, &context);
  /* Get a value to use for the quantize call.  */
  decNumberFromString (&qval, (char *) "1.", &context);
  /* Force the exponent to zero.  */
  decNumberQuantize (&n1, &n2, &qval, &context);
  /* Get a string, which at this point will not include an exponent.  */
  decNumberToString (&n1, buf);
  /* Ignore the fractional part.  */
  pos = strchr (buf, '.');
  if (pos)
    *pos = 0;
  /* Use a C library function to convert to the integral type.  */
  return STR_TO_INT (buf, NULL, 10);
}
Example #16
0
int main(int argc, char *argv[]) {
  int need=3;
  if (argc<need+1) {               // not enough words
    printf("Please supply %d number(s).\n", need);
    return 1;
    }

  { // excerpt for User's Guide starts here--------------------------|
  decNumber one, mtwo, hundred;                   // constants
  decNumber start, rate, years;                   // parameters
  decNumber total;                                // result
  decContext set;                                 // working context
  char string[DECNUMDIGITS+14];                   // conversion buffer

  decContextDefault(&set, DEC_INIT_BASE);         // initialize
  set.traps=0;                                    // no traps
  set.digits=25;                                  // precision 25
  decNumberFromString(&one,       "1", &set);     // set constants
  decNumberFromString(&mtwo,     "-2", &set);
  decNumberFromString(&hundred, "100", &set);

  decNumberFromString(&start, argv[1], &set);     // parameter words
  decNumberFromString(&rate,  argv[2], &set);
  decNumberFromString(&years, argv[3], &set);

  decNumberDivide(&rate, &rate, &hundred, &set);  // rate=rate/100
  decNumberAdd(&rate, &rate, &one, &set);         // rate=rate+1
  decNumberPower(&rate, &rate, &years, &set);     // rate=rate^years
  decNumberMultiply(&total, &rate, &start, &set); // total=rate*start
  decNumberRescale(&total, &total, &mtwo, &set);  // two digits please

  decNumberToString(&total, string);
  printf("%s at %s%% for %s years => %s\n",
         argv[1], argv[2], argv[3], string);

  } //---------------------------------------------------------------|
  return 0;
  } // main
Example #17
0
void int_to_dn(decNumber *x, int n, decContext *ctx) {
	char buf[12];

	sprintf(buf, "%d", n);
	decNumberFromString(x, buf, ctx);
}
Example #18
0
const DecimalDecNumber DecimalDecNumber::round(uint32 decimalPlaces, RoundingMode mode, RoundIncrement roundIncrement)
{
   if (isZero())
      return *this;

   if (roundIncrement == RoundIncrement::HALF)
      decNumberMultiply(&m_value, &m_value, &DecimalDecNumber::TWO.m_value, &m_context);
   else if (roundIncrement == RoundIncrement::QUARTER)
      decNumberMultiply(&m_value, &m_value, &DecimalDecNumber::FOUR.m_value, &m_context);

   static const int BUFFER_SIZE = 256;
   char buffer[BUFFER_SIZE];
   decNumberToString(&m_value, buffer);

   char * b = buffer;
   char * e = buffer + strlen(buffer);
   char * f = std::find(b, e, 'E');
   if (f != e && (f+1) != e)
   {
      unpackScientificFormat(b, e, BUFFER_SIZE, 48);
      e = buffer + strlen(buffer);
   }

   const char * point = std::find(buffer, e, '.');

   const char * firstNonZeroDigitAfterDecimal = point;
   while (firstNonZeroDigitAfterDecimal != e && (*firstNonZeroDigitAfterDecimal < '1' || *firstNonZeroDigitAfterDecimal > '9'))
   {
      ++firstNonZeroDigitAfterDecimal;
   }

   if (firstNonZeroDigitAfterDecimal != e)
   {
      decContext tempContext;
      decContextDefault(&tempContext, DEC_INIT_BASE); 
      tempContext.traps = 0;

      // DecNumber rounding is expressed in significant figures; we want to round to a fixed number of decimal places.
      const char * firstDigit = *buffer == '-' ? (buffer+1) : buffer;
      const bool absValueLessThanOne = *firstDigit == '0';
      if (absValueLessThanOne)
      {
         tempContext.digits = decimalPlaces - (firstNonZeroDigitAfterDecimal - point - 1);

      }
      else
      {
         tempContext.digits = decimalPlaces + (point - firstDigit);
      }
      if (tempContext.digits < 0)
      {
         decNumberFromInt32(&m_value, 0);
         return *this;
      }
		 
      switch (mode)
      {
         case RoundingMode::ROUND_HALF_TO_POSITIVE_INFINITY:
            tempContext.round = isNegative() ? DEC_ROUND_HALF_DOWN : DEC_ROUND_HALF_UP;
         break;
         case RoundingMode::ROUND_HALF_TO_NEGATIVE_INFINITY: 
            tempContext.round = isNegative() ? DEC_ROUND_HALF_UP : DEC_ROUND_HALF_DOWN;
         break;
         case RoundingMode::ROUND_TO_POSITIVE_INFINITY:
            tempContext.round = isNegative() ? DEC_ROUND_DOWN : DEC_ROUND_UP;
         break;
         case RoundingMode::ROUND_TO_NEGATIVE_INFINITY:
            tempContext.round = isNegative() ? DEC_ROUND_UP : DEC_ROUND_DOWN;
         break;
         case RoundingMode::ROUND_AWAY_FROM_ZERO:
            tempContext.round = DEC_ROUND_UP;
         break;
         case RoundingMode::ROUND_TO_ZERO:
            tempContext.round = DEC_ROUND_DOWN;
         break;
         case RoundingMode::ROUND_HALF_AWAY_FROM_ZERO: 
            tempContext.round = DEC_ROUND_HALF_UP;
         break;
         case RoundingMode::ROUND_HALF_TO_ZERO: 
            tempContext.round = DEC_ROUND_HALF_DOWN; 
         break;
         case RoundingMode::ROUND_HALF_TO_EVEN:
            tempContext.round = DEC_ROUND_HALF_EVEN; 
         break;
         default :
            throw("Rounding mode is not supported - rounding using default mode which is DEC_ROUND_HALF_AWAY_FROM_ZERO");
            // LCRIT("Rounding mode[%d] is not supported - rounding using default mode which is DEC_ROUND_HALF_AWAY_FROM_ZERO", mode);
            // tempContext.round = DEC_ROUND_HALF_UP;
      }

      decNumberFromString(&m_value, buffer, &tempContext);
   }

   if (roundIncrement == RoundIncrement::HALF)
      decNumberDivide(&m_value, &m_value, &DecimalDecNumber::TWO.m_value, &m_context);
   else if (roundIncrement == RoundIncrement::QUARTER)
      decNumberDivide(&m_value, &m_value, &DecimalDecNumber::FOUR.m_value, &m_context);

   return *this;
}