/* DEC *ConvDoubleToDecimalRound( x, f, nid) * * ARGUMENT * DEC *x; * double f; * int nid; * * DESCRIPTION * Converts a double to a DEC with implied decimal nid. Uses * eTwoTo32 (2^32), eTwoTo63 (2^63), and ergGMPowersOfTenDouble * (powers of ten), all global double variables. * * SIDE EFFECTS * None. * * RETURNS * The DEC if the conversion is successful, and GM_NULL otherwise. * * POSSIBLE ERROR CODES * * GM_NOMEMORY * GM_CNVRE * GM_INVALIDID * * AUTHOR * Jared Levy Feb. 9, 1987 * Copyright (C) 1987-1990 Greenleaf Software Inc. All rights reserved. * * MODIFICATIONS * * */ #include #include "gm.h" #include "gmsystem.h" DEC *ConvDoubleToDecimalRound( x, f, nid) DEC *x; double f; int nid; { mbool wfIsNeg=FALSE; double g; _MacStart(GM_DFTODR); if ((nid > GM_MAXID) || (nid < GM_MINID)) { _MacErr(GM_INVALIDID); _MacRet(GM_NULL); } _MacOutVarD(x); /* f = 0 */ if (f == 0.0) { _MacDZero(x); _MacRet(x); } /* take absolute value of negative values */ if (f<0.0) { wfIsNeg = TRUE; f = -f; } /* adjust by power of 10 */ if (nid > 0) { f*= ergGMPowersOfTenDouble[nid]; } _MacDZero(x); /* overflow and underflow */ if ((f>=eTwoTo63) || (f<0.5)) { _MacErr(GM_CNVRE); _MacRet(GM_NULL); } /* add .5 to round rather than truncate */ f+= 0.5; /* change float to 64 bit integer */ if (f >= eTwoTo32-1) { #ifdef ZORTECH if ( (f / eTwoTo32) > eTwoTo31 ) { x->ls.lsl[1] = (unsigned long) ((f / eTwoTo32) - eTwoTo31 ); x->ls.lsl[1] += (unsigned long) eTwoTo31; } else x->ls.lsl[1] = (unsigned long) (f / eTwoTo32); #else x->ls.lsl[1] = (unsigned long) (f / eTwoTo32); #endif g = (double) x->ls.lsl[1]; if (g<0.0) g+= eTwoTo32; f = f - g * eTwoTo32; while (f<0.0) { x->ls.lsl[1]--; f+= eTwoTo32; } while (f>= eTwoTo32) { x->ls.lsl[1]++; f-= eTwoTo32; } } #ifdef ZORTECH if ( f > eTwoTo31 ) { x->ls.lsl[0] = f - eTwoTo31; x->ls.lsl[0] += (unsigned long) eTwoTo31; } else x->ls.lsl[0] = (unsigned long) f; #else x->ls.lsl[0] = (unsigned long) f; #endif x->ls.lid = nid; if (wfIsNeg) _MacDChgs(x); _MacRet(x); }