/* 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; }
/* Use decNumber to convert directly from _Decimal64 to _Decimal32. */ _Decimal32 DFP_TO_DFP (_Decimal64 f_from) { union { _Decimal32 c; decSingle f; } to; union { _Decimal64 c; decDouble f; } from; decContext context; decContextDefault (&context, CONTEXT_INIT); DFP_INIT_ROUNDMODE (context.round); from.c = f_from; to.f = *decSingleFromWider (&to.f, &from.f, &context); if (DFP_EXCEPTIONS_ENABLED && context.status != 0) dfp_conversion_exceptions (context.status); return to.c; }
_Decimal32 /* Use decNumber to convert directly from integer to decimal float types. */ INT_TO_DFP (INT_TYPE i) { union { _Decimal32 c; decSingle f; } u32; decDouble f64; decContext context; decContextDefault (&context, DEC_INIT_DECIMAL128); context.round = DEC_ROUND_DOWN; f64 = *DEC_FLOAT_FROM_INT (&f64, i); u32.f = *decSingleFromWider (&u32.f, &f64, &context); if (DFP_EXCEPTIONS_ENABLED && context.status != 0) dfp_conversion_exceptions (context.status); return u32.c; }
QDecSingle& QDecSingle::fromWider(const QDecDouble& d, QDecContext* c) { decSingleFromWider(&m_data, d.data(), CXT(c)); return *this; }