/* 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); }