DEST_TYPE PREFIXED_FUNCTION_NAME (SRC_TYPE a) { DEST_TYPE result; decNumber d; decContext context; IEEE_SRC_TYPE e; IEEE_DEST_TYPE r; decContextDefault(&context, CONTEXT_INIT); context.round = __dn_getround(); PASTE(___host_to_ieee_,SRC) ((&a), &e); PASTE(decimal,PASTE(SRC,ToNumber))(&e, &d); /* PASTE(___decimal,PASTE(SRC,ToNumber))(&a, &d); */ /* PASTE(___decimal,PASTE(DEST,FromNumber))(&result, &d, &context); */ PASTE(decimal,PASTE(DEST,FromNumber))(&r, &d, &context); PASTE(PASTE(___ieee_,DEST),_to_host) (&r, (&result)); if (context.status != 0) { int dec_flags = context.status & (DEC_IEEE_854_Inexact|DEC_IEEE_854_Invalid_operation); DFP_HANDLE_EXCEPTIONS(DFP_IEEE_FLAGS(dec_flags)); } return result; }
DEST_TYPE PREFIXED_FUNCTION_NAME (SRC_TYPE a) { DEST_TYPE f; char buf[BUFMAX]; decContext context; IEEE_DEST_TYPE e; decContextDefault (&context, CONTEXT_INIT); context.round = DEC_ROUND_HALF_EVEN; /* Use a C library function to get a floating point string. */ sprintf (buf, INT_FMT "", CAST_FOR_FMT(a)); /* Convert from the floating point string to a decimal* type. */ /* PASTE(___decimal,PASTE(DEST,FromString))(&f, buf, &context); */ PASTE(decimal,PASTE(DEST,FromString))(&e, buf, &context); PASTE(PASTE(___ieee_,DEST),_to_host) (&e, (&f)); if (context.status != 0) { int dec_flags = context.status & (DEC_IEEE_854_Inexact|DEC_IEEE_854_Invalid_operation|DEC_IEEE_854_Overflow); DFP_HANDLE_EXCEPTIONS(DFP_IEEE_FLAGS(dec_flags)); } return f; }
/* 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 a decFloat (decDouble or decQuad) function to perform a DFP binary operation. */ static inline decFloat dfp_binary_op (dfp_binary_func op, decFloat arg_a, decFloat arg_b) { decFloat result; decContext context; decContextDefault (&context, CONTEXT_INIT); DFP_INIT_ROUNDMODE (context.round); /* Perform the operation. */ op (&result, &arg_a, &arg_b, &context); if (DFP_EXCEPTIONS_ENABLED && context.status != 0) { /* decNumber exception flags we care about here. */ int ieee_flags; int dec_flags = DEC_IEEE_854_Division_by_zero | DEC_IEEE_854_Inexact | DEC_IEEE_854_Invalid_operation | 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 result; }
DFP_C_TYPE BFP_TO_DFP (BFP_TYPE x) { DFP_C_TYPE f; IEEE_TYPE s; char buf[BUFMAX]; decContext context; decContextDefault (&context, CONTEXT_INIT); DFP_INIT_ROUNDMODE (context.round); /* Use a C library function to write the floating point value to a string. */ sprintf (buf, BFP_FMT, (BFP_VIA_TYPE) x); /* Convert from the floating point string to a decimal* type. */ FROM_STRING (&s, buf, &context); IEEE_TO_HOST (s, &f); 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_Invalid_operation | 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 f; }
/* Check for floating point exceptions that are relevant for conversions between decimal float values and handle them. */ static inline void dfp_conversion_exceptions (const int status) { /* decNumber exception flags we care about here. */ int ieee_flags; int dec_flags = DEC_IEEE_854_Inexact | DEC_IEEE_854_Invalid_operation | DEC_IEEE_854_Overflow; dec_flags &= status; ieee_flags = DFP_IEEE_FLAGS (dec_flags); if (ieee_flags != 0) DFP_HANDLE_EXCEPTIONS (ieee_flags); }