/* 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;
}
/* The decNumber package doesn't provide comparisons for decSingle (32 bits);
   convert to decDouble, use the operation for that, and convert back.  */
static inline CMPtype
d32_compare_op (dfp_binary_func op, _Decimal32 arg_a, _Decimal32 arg_b)
{
  union { _Decimal32 c; decSingle f; } a32, b32;
  decDouble a, b;

  a32.c = arg_a;
  b32.c = arg_b;
  decSingleToWider (&a32.f, &a);
  decSingleToWider (&b32.f, &b);
  return dfp_compare_op (op, a, b);  
}
/* Use decNumber to convert directly from _Decimal32 to _Decimal64.  */
_Decimal64
DFP_TO_DFP (_Decimal32 f_from)
{
  union { _Decimal32 c; decSingle f; } from;
  union { _Decimal64 c; decDouble f; } to;

  from.c = f_from;
  to.f = *decSingleToWider (&from.f, &to.f);
  return to.c;
}
/* Use decNumber to convert directly from _Decimal32 to _Decimal128.  */
_Decimal128
DFP_TO_DFP (_Decimal32 f_from)
{
  union { _Decimal32 c; decSingle f; } from;
  union { _Decimal128 c; decQuad f; } to;
  decDouble temp;

  from.c = f_from;
  temp = *decSingleToWider (&from.f, &temp);
  to.f = *decDoubleToWider (&temp, &to.f);
  return to.c;
}
/* Use decNumber to convert directly from decimal float to integer types.  */
INT_TYPE
DFP_TO_INT (_Decimal32 x)
{
  union { _Decimal32 c; decSingle f; } u32;
  decDouble f64;
  decContext context;
  INT_TYPE i;

  decContextDefault (&context, DEC_INIT_DECIMAL128);
  context.round = DEC_ROUND_DOWN;
  u32.c = x;
  f64 = *decSingleToWider (&u32.f, &f64);
  i = DEC_FLOAT_TO_INT (&f64, &context, context.round);
  if (DFP_EXCEPTIONS_ENABLED && context.status != 0)
    dfp_conversion_exceptions (context.status);
  return i;
}
uint32_t decSingleToUInt32Exact (const decSingle* _0, decContext* _1, int32_t _2) noexcept
{
  decDouble r;
  decSingleToWider (_0, &r);
  return decDoubleToUInt32Exact (&r, _1, (enum rounding)_2);
}
int32_t decSingleToInt32 (const decSingle* _0, decContext* ctx, int32_t _2) noexcept
{
  decDouble r;
  decSingleToWider (_0, &r);
  return decDoubleToInt32 (&r, ctx, (enum rounding)_2);
}
QDecDouble QDecSingle::toWider() const
{
  decDouble d;
  return decSingleToWider(&m_data, &d);
}