/* The decNumber package doesn't provide arithmetic for decSingle (32 bits);
   convert to decDouble, use the operation for that, and convert back.  */
static inline _Decimal32
d32_binary_op (dfp_binary_func op, _Decimal32 arg_a, _Decimal32 arg_b)
{
  union { _Decimal32 c; decSingle f; } a32, b32, res32;
  decDouble a, b, res;
  decContext context;

  /* Widen the operands and perform the operation.  */
  a32.c = arg_a;
  b32.c = arg_b;
  decSingleToWider (&a32.f, &a);
  decSingleToWider (&b32.f, &b);
  res = dfp_binary_op (op, a, b);

  /* Narrow the result, which might result in an underflow or overflow.  */
  decContextDefault (&context, CONTEXT_INIT);
  DFP_INIT_ROUNDMODE (context.round);
  decSingleFromWider (&res32.f, &res, &context);
  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
    {
      /* decNumber exception flags we care about here.  */
      int ieee_flags;
      int dec_flags = DEC_IEEE_854_Inexact | DEC_IEEE_854_Overflow
		      | DEC_IEEE_854_Underflow;
      dec_flags &= context.status;
      ieee_flags = DFP_IEEE_FLAGS (dec_flags);
      if (ieee_flags != 0)
        DFP_HANDLE_EXCEPTIONS (ieee_flags);
    }

  return res32.c;
}
/* decFloat operations are supported for decDouble (64 bits) and
   decQuad (128 bits).  The bit patterns for the types are the same.  */
static inline DFP_C_TYPE
dnn_binary_op (dfp_binary_func op, DFP_C_TYPE arg_a, DFP_C_TYPE arg_b)
{
  union { DFP_C_TYPE c; decFloat f; } a, b, result;

  a.c = arg_a;
  b.c = arg_b;
  result.f = dfp_binary_op (op, a.f, b.f);
  return result.c;
}
Beispiel #3
0
DFP_C_TYPE
DFP_DIVIDE (DFP_C_TYPE arg_a, DFP_C_TYPE arg_b)
{
  return dfp_binary_op (decNumberDivide, arg_a, arg_b);
}
Beispiel #4
0
DFP_C_TYPE
DFP_MULTIPLY (DFP_C_TYPE arg_a, DFP_C_TYPE arg_b)
{
  return dfp_binary_op (decNumberMultiply, arg_a, arg_b);
}
Beispiel #5
0
DFP_C_TYPE
DFP_SUB (DFP_C_TYPE arg_a, DFP_C_TYPE arg_b)
{
  return dfp_binary_op (decNumberSubtract, arg_a, arg_b);
}
Beispiel #6
0
DFP_C_TYPE
DFP_ADD (DFP_C_TYPE arg_a, DFP_C_TYPE arg_b)
{
  return dfp_binary_op (decNumberAdd, arg_a, arg_b);
}