예제 #1
0
파일: subsd3.c 프로젝트: gftg85/libdfp
DEC_TYPE
PREFIXED_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
{
  DEC_TYPE result;
  decNumber dn_x, dn_y, dn_result;
  decContext context;
  decContextDefault(&context, DEFAULT_CONTEXT);

  FUNC_CONVERT_TO_DN(&x, &dn_x);
  FUNC_CONVERT_TO_DN(&y, &dn_y);

  decNumberSubtract(&dn_result, &dn_x, &dn_y, &context);

  if (context.status != 0)
    {
      int ieee_flags = 0;
      if (context.status & DEC_IEEE_854_Division_by_zero)
        ieee_flags |= FE_DIVBYZERO;
      if (context.status & DEC_IEEE_854_Inexact)
        ieee_flags |= FE_INEXACT;
      if (context.status & DEC_IEEE_854_Invalid_operation)
        ieee_flags |= FE_INVALID;
      if (context.status & DEC_IEEE_854_Overflow)
        ieee_flags |= FE_OVERFLOW;
      if (context.status & DEC_IEEE_854_Underflow)
        ieee_flags |= FE_UNDERFLOW;
      if (ieee_flags != 0)
        feraiseexcept (ieee_flags);
    }

  FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
  return result;
}
예제 #2
0
파일: zetaconsts.c 프로젝트: BigEd/wp34s
int main(int argc, char *argv[]) {
	int i;
	const int N = 30;	// At 15 the second last term is the same as the last
	decNumber di, dn;
	char s[10000];

	decContext ctx;

	decContextDefault(&ctx, DEC_INIT_BASE);
	ctx.traps = 0;
	ctx.digits = DECNUMDIGITS;
	ctx.emax=DEC_MAX_MATH;
	ctx.emin=-DEC_MAX_MATH;
	ctx.round = DEC_ROUND_HALF_EVEN;

	zetadk(&dn, N, N, &ctx);
	decNumberToString(&dn, s);
	printf("\t{ DFLT, \"zeta_dn\",\t\t\"%s\"\t},\n", s);
	for (i=0; i<N; i++) {
		zetadk(&di, N, i, &ctx);
		decNumberSubtract(&di, &dn, &di, &ctx);
		decNumberToString(&di, s);
		printf("\t{ DFLT, \"zetaC%02d\",\t\t\"%s\"\t},\n",
				i, s);
	}
	return 0;
}
예제 #3
0
int DecimalDecNumber::comparedTo(const DecimalDecNumber &rhs) const
{
	if (decNumberIsNaN(&m_value) || decNumberIsNaN(&rhs.m_value))
	{
		throw("Performing comparison on uninitialised decimal [Nan]");
	}

   // TODO: the commented out lines below do a strict comparison between two numbers.
   // However, the unit tests assert that comparison should be done within a tolerance
   //decNumberCompare(&result, &m_value, &rhs.m_value, &contextComparison);
   //return decNumberToInt32(&result, &m_context);

   decContext contextComparison;
   decContextDefault(&contextComparison, DEC_INIT_BASE); // initialize
   contextComparison.traps=0;                            // no traps, thank you
   contextComparison.digits=DECNUMCOMPARISONDIGITS;      // set precision

   decNumber tmp(m_value);
   decNumberSubtract(&tmp, &m_value, &rhs.m_value, &m_context);

   decNumber result;
   decNumberCompare(&result, &tmp, &comparisonThreshold.m_value, &contextComparison);
   if (decNumberToInt32(&result, &m_context) >= 1)
   {
      return 1;
   }

   decNumberCompare(&result, &tmp, &comparisonThresholdNegative.m_value, &contextComparison);
   if (decNumberToInt32(&result, &m_context) <= -1)
   {
      return -1;
   }
   return 0;
}
예제 #4
0
파일: expm1d32.c 프로젝트: gftg85/libdfp
static DEC_TYPE
IEEE_FUNCTION_NAME (DEC_TYPE x)
{
  decContext context;
  decNumber dn_result;
  DEC_TYPE result;
  decNumber dn_x;
  decNumber dn_one;
  decNumber dn_exponent;
  DEC_TYPE one = DFP_CONSTANT(1.0);

  FUNC_CONVERT_TO_DN(&x, &dn_x);
  FUNC_CONVERT_TO_DN(&one, &dn_one);
  if (decNumberIsNaN (&dn_x))
    return x+x;

  if (decNumberIsInfinite (&dn_x))
    return decNumberIsNegative (&dn_x) ? DFP_CONSTANT(-1.0) : x;

  decContextDefault(&context, DEFAULT_CONTEXT);
  decNumberExp(&dn_exponent, &dn_x, &context);
  decNumberSubtract(&dn_result, &dn_exponent, &dn_one, &context);

  FUNC_CONVERT_FROM_DN(&dn_result, &result, &context);
  if (context.status & DEC_Overflow)
    DFP_EXCEPT (FE_OVERFLOW);

  return result;
}
예제 #5
0
void* decSingleSubtract (decSingle* _0, const decSingle* _1, const decSingle* _2, decContext* ctx) noexcept
{
  decNumber _0num;
  decNumber _1num;
  decNumber _2num;
  decSingleToNumber (_1, &_1num);
  decSingleToNumber (_2, &_2num);
  decNumberSubtract (&_0num, &_1num, &_2num, ctx);
  return decSingleFromNumber (_0, &_0num, ctx);
}
예제 #6
0
const DecimalDecNumber &DecimalDecNumber::operator --()
{
	if (decNumberIsNaN(&m_value))
	{
		throw("Performing arithmetic on uninitialised decimal [Nan]");
	}

   decNumberSubtract(&m_value, &m_value, &ONE.m_value, &m_context);
	return *this;
}
예제 #7
0
DecimalDecNumber DecimalDecNumber::distance(const DecimalDecNumber &rhs) const
{
   decContext contextComparison;
   decContextDefault(&contextComparison, DEC_INIT_BASE); // initialize
   contextComparison.traps=0;                            // no traps, thank you
   contextComparison.digits=DECNUMCOMPARISONDIGITS;      // set precision

	DecimalDecNumber distance;
   decNumberSubtract(&distance.m_value, &m_value, &rhs.m_value, &m_context);
   return abs(distance);
}
예제 #8
0
const DecimalDecNumber &DecimalDecNumber::operator -=(const DecimalDecNumber &rhs)
{
	if (decNumberIsNaN(&m_value) || decNumberIsNaN(&rhs.m_value))
	{
		// FTHROW(InvalidStateException, "Performing arithmetic on uninitialised decimal [Nan]");
		throw("Performing arithmetic on uninitialised decimal [Nan]");
	}

   decNumberSubtract(&m_value, &m_value, &rhs.m_value, &m_context);
	return *this;
}
예제 #9
0
파일: atanhd32.c 프로젝트: rzinsly/libdfp
static DEC_TYPE
IEEE_FUNCTION_NAME (DEC_TYPE x)
{
  decContext context;
  decNumber dn_result;
  DEC_TYPE result, one, temp;
  decNumber dn_x, dn_temp, dn_one;
/*  int comp;*/

  one=DFP_CONSTANT(1.0);
  FUNC_CONVERT_TO_DN (&one, &dn_one);
  FUNC_CONVERT_TO_DN (&x, &dn_x);

  /*  Handle NaN and early exit for x==0 */
  if (decNumberIsNaN (&dn_x) || decNumberIsZero (&dn_x))
    return x + x;

  decContextDefault (&context, DEFAULT_CONTEXT);
  decNumberAbs (&dn_temp, &dn_x, &context);

  FUNC_CONVERT_FROM_DN (&dn_temp, &temp, &context);
  if(temp==one) {
	/*  |x| == 1 -> Pole Error */
	DFP_EXCEPT (FE_DIVBYZERO);
	return decNumberIsNegative(&dn_x) ? -DFP_HUGE_VAL:DFP_HUGE_VAL;
  } else if (temp>one) {
	/*  |x| > 1 -> Domain Error (this handles +-Inf too) */
	DFP_EXCEPT (FE_INVALID);
	return DFP_NAN;
  }

//  comp = decCompare (&dn_temp, &dn_one);
//  switch (comp)
//    {
//      case 0: /*  |x| == 1 -> Pole Error */
//	DFP_EXCEPT (FE_DIVBYZERO);
//	return decNumberIsNegative(&dn_x) ? -DFP_HUGE_VAL:DFP_HUGE_VAL;
//      case 1: /*  |x| > 1 -> Domain Error (this handles +-Inf too) */
//	DFP_EXCEPT (FE_INVALID);
//	return DFP_NAN;
//    }

  /* Using trig identity: atanh(x) = 1/2 * log((1+x)/(1-x)) */
  decNumberAdd (&dn_result, &dn_one, &dn_x, &context);
  decNumberSubtract (&dn_temp, &dn_one, &dn_x, &context);
  decNumberDivide (&dn_result, &dn_result, &dn_temp, &context);
  decNumberLn (&dn_result, &dn_result, &context);
  decNumberAdd (&dn_temp, &dn_one, &dn_one, &context); /* 2 */
  decNumberDivide (&dn_result, &dn_result, &dn_temp, &context);

  FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);

  return result;
}
예제 #10
0
파일: fdimd32.c 프로젝트: gftg85/libdfp
static DEC_TYPE
IEEE_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
{
  decContext context;
  decNumber dn_result;
  DEC_TYPE result;
  decNumber dn_x;
  decNumber dn_y;
  decNumber dn_diff;
  DEC_TYPE temp_diff;
  DEC_TYPE temp_result;

  FUNC_CONVERT_TO_DN (&x, &dn_x);
  FUNC_CONVERT_TO_DN (&y, &dn_y);

  if(decNumberIsNaN (&dn_x) || decNumberIsNaN (&dn_y))
    return x;

  decContextDefault (&context, DEFAULT_CONTEXT);
  decNumberSubtract (&dn_diff, &dn_x, &dn_y, &context);
  decNumberSubtract (&dn_result, &dn_x, &dn_x, &context);

  FUNC_CONVERT_FROM_DN (&dn_diff, &temp_diff, &context);
  FUNC_CONVERT_FROM_DN (&dn_result, &temp_result, &context);
  if(temp_diff>temp_result)
    decNumberAdd (&dn_result,&dn_result,&dn_diff,&context);
 /* if(decCompare (&dn_diff,&dn_result) == 1)
    decNumberAdd (&dn_result,&dn_result,&dn_diff,&context);
    */

  FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);
  if (context.status & DEC_Overflow)
    DFP_EXCEPT (FE_OVERFLOW);

  return result;
}
예제 #11
0
파일: zetaconsts.c 프로젝트: BigEd/wp34s
/* Compute a factorial.
 * Currently, only for positive integer arguments.  Needs to be extended
 * to a full gamma function.
 */
decNumber *decNumberFactorial(decNumber *r, const decNumber *x, decContext *ctx) {
	decNumber y, const_1;

	int_to_dn(&const_1, 1, ctx);
	decNumberCopy(&y, x);
	if (!decNumberIsNegative(x) || decNumberIsZero(x)) {
		decNumberCopy(r, &const_1);
		for (;;) {
			if (decNumberIsZero(&y))
				break;
			if (decNumberIsInfinite(r))
				break;
			decNumberMultiply(r, r, &y, ctx);
			decNumberSubtract(&y, &y, &const_1, ctx);
		}
	}
	return r;
}
예제 #12
0
파일: powd32.c 프로젝트: gftg85/libdfp
static DEC_TYPE
IEEE_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y)
{
  decContext context;
  decNumber dn_result;
  DEC_TYPE result;
  DEC_TYPE absx;
  decNumber dn_x;
  decNumber dn_absx;
  decNumber dn_y;
  decNumber dn_one;
  decNumber dn_two;
  decNumber dn_temp;
  decNumber dn_temp2;
  decNumber dn_temp3;
  int y_is_int;
  int y_is_oddint=0;
  int abs_x_vs_1;
  DEC_TYPE one = DFP_CONSTANT(1.0);
  DEC_TYPE two = DFP_CONSTANT(2.0);

  FUNC_CONVERT_TO_DN (&x, &dn_x);
  FUNC_CONVERT_TO_DN (&y, &dn_y);
  FUNC_CONVERT_TO_DN (&one, &dn_one);

  decContextDefault (&context, DEFAULT_CONTEXT);
  if (decNumberIsZero (&dn_y))
    return one;
  if (decNumberIsNaN (&dn_x))
    return x+x;

  decNumberAbs (&dn_absx, &dn_x, &context);

  FUNC_CONVERT_FROM_DN (&dn_absx, &absx, &context);
  if(absx<one)
    abs_x_vs_1 = -1;
  else if (absx==one)
    abs_x_vs_1 = 0;
  else
    abs_x_vs_1 = 1;

/*  abs_x_vs_1 = decCompare(&dn_absx, &dn_one); */
  if(abs_x_vs_1 == 0 && !decNumberIsNegative (&dn_x)) /*  If x == +1 */
    return one;
  if (decNumberIsNaN (&dn_y))
    return y+y;

  /*  Detect if y is odd/an integer */
  decNumberToIntegralValue (&dn_temp, &dn_y, &context);
  decNumberSubtract (&dn_temp2, &dn_temp, &dn_y, &context);
  y_is_int = decNumberIsZero (&dn_temp2);
  if (y_is_int)
    {
      FUNC_CONVERT_TO_DN (&two, &dn_two);
      decNumberDivide (&dn_temp, &dn_y, &dn_two, &context);
      decNumberToIntegralValue (&dn_temp2, &dn_temp, &context);
      decNumberSubtract (&dn_temp3, &dn_temp2, &dn_temp, &context);
      y_is_oddint = !decNumberIsZero (&dn_temp3);
    }

  /*  Handle all special cases for which x = +-0 */
  if (decNumberIsZero (&dn_x))
    {
      if(decNumberIsNegative (&dn_y))
	{
	  if (decNumberIsInfinite (&dn_y))	/*  +-0^-Inf = +Inf */
	    return -y;
	  /*  Pole Error for x = +-0, y < 0 */
	  DFP_EXCEPT (FE_DIVBYZERO);
	  return decNumberIsNegative(&dn_x) && y_is_oddint ?
		-DFP_HUGE_VAL : DFP_HUGE_VAL;
	}
      return decNumberIsNegative(&dn_x) && y_is_oddint ?
		-DFP_CONSTANT(0.0) : DFP_CONSTANT(0.0);
    }

  /* Handle remaining special cases for x = +-Inf or y = +-Inf */
  if (decNumberIsInfinite (&dn_x) || decNumberIsInfinite (&dn_y))
    {
      if (abs_x_vs_1 == 0)	/*  If (-1)^(+-Inf) */
	return one;
      if (abs_x_vs_1 < 0)	/*  x^(+-Inf), where 0<x<1 */
	return decNumberIsNegative (&dn_y) ? DFP_HUGE_VAL
		: DFP_CONSTANT(0.0);
      if (decNumberIsNegative (&dn_y))
	result = DFP_CONSTANT(0.0);
      else
	result = (DEC_TYPE)DEC_INFINITY;
      if (y_is_oddint && decNumberIsNegative(&dn_x))
	result = -result;
      return result;
    }

  /* Domain Error: x < 0 && y is a finite non-int */
  if (decNumberIsNegative (&dn_x) && !y_is_int)
    {
      DFP_EXCEPT (FE_INVALID);
      return DFP_NAN;
    }

  decNumberPower (&dn_result, &dn_x, &dn_y, &context);
  FUNC_CONVERT_FROM_DN (&dn_result, &result, &context);

  if (context.status & DEC_Overflow)
    DFP_EXCEPT (FE_OVERFLOW);
  if (context.status & DEC_Underflow)
    DFP_EXCEPT (FE_UNDERFLOW);

  return result;
}