1*72ac97cdSTom Musta /* Decimal context module for the decNumber C Library. 2*72ac97cdSTom Musta Copyright (C) 2005, 2007 Free Software Foundation, Inc. 3*72ac97cdSTom Musta Contributed by IBM Corporation. Author Mike Cowlishaw. 4*72ac97cdSTom Musta 5*72ac97cdSTom Musta This file is part of GCC. 6*72ac97cdSTom Musta 7*72ac97cdSTom Musta GCC is free software; you can redistribute it and/or modify it under 8*72ac97cdSTom Musta the terms of the GNU General Public License as published by the Free 9*72ac97cdSTom Musta Software Foundation; either version 2, or (at your option) any later 10*72ac97cdSTom Musta version. 11*72ac97cdSTom Musta 12*72ac97cdSTom Musta In addition to the permissions in the GNU General Public License, 13*72ac97cdSTom Musta the Free Software Foundation gives you unlimited permission to link 14*72ac97cdSTom Musta the compiled version of this file into combinations with other 15*72ac97cdSTom Musta programs, and to distribute those combinations without any 16*72ac97cdSTom Musta restriction coming from the use of this file. (The General Public 17*72ac97cdSTom Musta License restrictions do apply in other respects; for example, they 18*72ac97cdSTom Musta cover modification of the file, and distribution when not linked 19*72ac97cdSTom Musta into a combine executable.) 20*72ac97cdSTom Musta 21*72ac97cdSTom Musta GCC is distributed in the hope that it will be useful, but WITHOUT ANY 22*72ac97cdSTom Musta WARRANTY; without even the implied warranty of MERCHANTABILITY or 23*72ac97cdSTom Musta FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 24*72ac97cdSTom Musta for more details. 25*72ac97cdSTom Musta 26*72ac97cdSTom Musta You should have received a copy of the GNU General Public License 27*72ac97cdSTom Musta along with GCC; see the file COPYING. If not, write to the Free 28*72ac97cdSTom Musta Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 29*72ac97cdSTom Musta 02110-1301, USA. */ 30*72ac97cdSTom Musta 31*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 32*72ac97cdSTom Musta /* Decimal Context module */ 33*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 34*72ac97cdSTom Musta /* This module comprises the routines for handling arithmetic */ 35*72ac97cdSTom Musta /* context structures. */ 36*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 37*72ac97cdSTom Musta 38*72ac97cdSTom Musta #include <string.h> /* for strcmp */ 39*72ac97cdSTom Musta #include <stdio.h> /* for printf if DECCHECK */ 40*72ac97cdSTom Musta #include "dconfig.h" /* for GCC definitions */ 41*72ac97cdSTom Musta #include "decContext.h" /* context and base types */ 42*72ac97cdSTom Musta #include "decNumberLocal.h" /* decNumber local types, etc. */ 43*72ac97cdSTom Musta 44*72ac97cdSTom Musta #if DECCHECK 45*72ac97cdSTom Musta /* compile-time endian tester [assumes sizeof(Int)>1] */ 46*72ac97cdSTom Musta static const Int mfcone=1; /* constant 1 */ 47*72ac97cdSTom Musta static const Flag *mfctop=(Flag *)&mfcone; /* -> top byte */ 48*72ac97cdSTom Musta #define LITEND *mfctop /* named flag; 1=little-endian */ 49*72ac97cdSTom Musta #endif 50*72ac97cdSTom Musta 51*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 52*72ac97cdSTom Musta /* round-for-reround digits */ 53*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 54*72ac97cdSTom Musta const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */ 55*72ac97cdSTom Musta 56*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 57*72ac97cdSTom Musta /* Powers of ten (powers[n]==10**n, 0<=n<=9) */ 58*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 59*72ac97cdSTom Musta const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000, 60*72ac97cdSTom Musta 10000000, 100000000, 1000000000}; 61*72ac97cdSTom Musta 62*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 63*72ac97cdSTom Musta /* decContextClearStatus -- clear bits in current status */ 64*72ac97cdSTom Musta /* */ 65*72ac97cdSTom Musta /* context is the context structure to be queried */ 66*72ac97cdSTom Musta /* mask indicates the bits to be cleared (the status bit that */ 67*72ac97cdSTom Musta /* corresponds to each 1 bit in the mask is cleared) */ 68*72ac97cdSTom Musta /* returns context */ 69*72ac97cdSTom Musta /* */ 70*72ac97cdSTom Musta /* No error is possible. */ 71*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 72*72ac97cdSTom Musta decContext *decContextClearStatus(decContext *context, uInt mask) { 73*72ac97cdSTom Musta context->status&=~mask; 74*72ac97cdSTom Musta return context; 75*72ac97cdSTom Musta } /* decContextClearStatus */ 76*72ac97cdSTom Musta 77*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 78*72ac97cdSTom Musta /* decContextDefault -- initialize a context structure */ 79*72ac97cdSTom Musta /* */ 80*72ac97cdSTom Musta /* context is the structure to be initialized */ 81*72ac97cdSTom Musta /* kind selects the required set of default values, one of: */ 82*72ac97cdSTom Musta /* DEC_INIT_BASE -- select ANSI X3-274 defaults */ 83*72ac97cdSTom Musta /* DEC_INIT_DECIMAL32 -- select IEEE 754r defaults, 32-bit */ 84*72ac97cdSTom Musta /* DEC_INIT_DECIMAL64 -- select IEEE 754r defaults, 64-bit */ 85*72ac97cdSTom Musta /* DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit */ 86*72ac97cdSTom Musta /* For any other value a valid context is returned, but with */ 87*72ac97cdSTom Musta /* Invalid_operation set in the status field. */ 88*72ac97cdSTom Musta /* returns a context structure with the appropriate initial values. */ 89*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 90*72ac97cdSTom Musta decContext * decContextDefault(decContext *context, Int kind) { 91*72ac97cdSTom Musta /* set defaults... */ 92*72ac97cdSTom Musta context->digits=9; /* 9 digits */ 93*72ac97cdSTom Musta context->emax=DEC_MAX_EMAX; /* 9-digit exponents */ 94*72ac97cdSTom Musta context->emin=DEC_MIN_EMIN; /* .. balanced */ 95*72ac97cdSTom Musta context->round=DEC_ROUND_HALF_UP; /* 0.5 rises */ 96*72ac97cdSTom Musta context->traps=DEC_Errors; /* all but informational */ 97*72ac97cdSTom Musta context->status=0; /* cleared */ 98*72ac97cdSTom Musta context->clamp=0; /* no clamping */ 99*72ac97cdSTom Musta #if DECSUBSET 100*72ac97cdSTom Musta context->extended=0; /* cleared */ 101*72ac97cdSTom Musta #endif 102*72ac97cdSTom Musta switch (kind) { 103*72ac97cdSTom Musta case DEC_INIT_BASE: 104*72ac97cdSTom Musta /* [use defaults] */ 105*72ac97cdSTom Musta break; 106*72ac97cdSTom Musta case DEC_INIT_DECIMAL32: 107*72ac97cdSTom Musta context->digits=7; /* digits */ 108*72ac97cdSTom Musta context->emax=96; /* Emax */ 109*72ac97cdSTom Musta context->emin=-95; /* Emin */ 110*72ac97cdSTom Musta context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ 111*72ac97cdSTom Musta context->traps=0; /* no traps set */ 112*72ac97cdSTom Musta context->clamp=1; /* clamp exponents */ 113*72ac97cdSTom Musta #if DECSUBSET 114*72ac97cdSTom Musta context->extended=1; /* set */ 115*72ac97cdSTom Musta #endif 116*72ac97cdSTom Musta break; 117*72ac97cdSTom Musta case DEC_INIT_DECIMAL64: 118*72ac97cdSTom Musta context->digits=16; /* digits */ 119*72ac97cdSTom Musta context->emax=384; /* Emax */ 120*72ac97cdSTom Musta context->emin=-383; /* Emin */ 121*72ac97cdSTom Musta context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ 122*72ac97cdSTom Musta context->traps=0; /* no traps set */ 123*72ac97cdSTom Musta context->clamp=1; /* clamp exponents */ 124*72ac97cdSTom Musta #if DECSUBSET 125*72ac97cdSTom Musta context->extended=1; /* set */ 126*72ac97cdSTom Musta #endif 127*72ac97cdSTom Musta break; 128*72ac97cdSTom Musta case DEC_INIT_DECIMAL128: 129*72ac97cdSTom Musta context->digits=34; /* digits */ 130*72ac97cdSTom Musta context->emax=6144; /* Emax */ 131*72ac97cdSTom Musta context->emin=-6143; /* Emin */ 132*72ac97cdSTom Musta context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ 133*72ac97cdSTom Musta context->traps=0; /* no traps set */ 134*72ac97cdSTom Musta context->clamp=1; /* clamp exponents */ 135*72ac97cdSTom Musta #if DECSUBSET 136*72ac97cdSTom Musta context->extended=1; /* set */ 137*72ac97cdSTom Musta #endif 138*72ac97cdSTom Musta break; 139*72ac97cdSTom Musta 140*72ac97cdSTom Musta default: /* invalid Kind */ 141*72ac97cdSTom Musta /* use defaults, and .. */ 142*72ac97cdSTom Musta decContextSetStatus(context, DEC_Invalid_operation); /* trap */ 143*72ac97cdSTom Musta } 144*72ac97cdSTom Musta 145*72ac97cdSTom Musta #if DECCHECK 146*72ac97cdSTom Musta if (LITEND!=DECLITEND) { 147*72ac97cdSTom Musta const char *adj; 148*72ac97cdSTom Musta if (LITEND) adj="little"; 149*72ac97cdSTom Musta else adj="big"; 150*72ac97cdSTom Musta printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n", 151*72ac97cdSTom Musta DECLITEND, adj); 152*72ac97cdSTom Musta } 153*72ac97cdSTom Musta #endif 154*72ac97cdSTom Musta return context;} /* decContextDefault */ 155*72ac97cdSTom Musta 156*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 157*72ac97cdSTom Musta /* decContextGetRounding -- return current rounding mode */ 158*72ac97cdSTom Musta /* */ 159*72ac97cdSTom Musta /* context is the context structure to be queried */ 160*72ac97cdSTom Musta /* returns the rounding mode */ 161*72ac97cdSTom Musta /* */ 162*72ac97cdSTom Musta /* No error is possible. */ 163*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 164*72ac97cdSTom Musta enum rounding decContextGetRounding(decContext *context) { 165*72ac97cdSTom Musta return context->round; 166*72ac97cdSTom Musta } /* decContextGetRounding */ 167*72ac97cdSTom Musta 168*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 169*72ac97cdSTom Musta /* decContextGetStatus -- return current status */ 170*72ac97cdSTom Musta /* */ 171*72ac97cdSTom Musta /* context is the context structure to be queried */ 172*72ac97cdSTom Musta /* returns status */ 173*72ac97cdSTom Musta /* */ 174*72ac97cdSTom Musta /* No error is possible. */ 175*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 176*72ac97cdSTom Musta uInt decContextGetStatus(decContext *context) { 177*72ac97cdSTom Musta return context->status; 178*72ac97cdSTom Musta } /* decContextGetStatus */ 179*72ac97cdSTom Musta 180*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 181*72ac97cdSTom Musta /* decContextRestoreStatus -- restore bits in current status */ 182*72ac97cdSTom Musta /* */ 183*72ac97cdSTom Musta /* context is the context structure to be updated */ 184*72ac97cdSTom Musta /* newstatus is the source for the bits to be restored */ 185*72ac97cdSTom Musta /* mask indicates the bits to be restored (the status bit that */ 186*72ac97cdSTom Musta /* corresponds to each 1 bit in the mask is set to the value of */ 187*72ac97cdSTom Musta /* the correspnding bit in newstatus) */ 188*72ac97cdSTom Musta /* returns context */ 189*72ac97cdSTom Musta /* */ 190*72ac97cdSTom Musta /* No error is possible. */ 191*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 192*72ac97cdSTom Musta decContext *decContextRestoreStatus(decContext *context, 193*72ac97cdSTom Musta uInt newstatus, uInt mask) { 194*72ac97cdSTom Musta context->status&=~mask; /* clear the selected bits */ 195*72ac97cdSTom Musta context->status|=(mask&newstatus); /* or in the new bits */ 196*72ac97cdSTom Musta return context; 197*72ac97cdSTom Musta } /* decContextRestoreStatus */ 198*72ac97cdSTom Musta 199*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 200*72ac97cdSTom Musta /* decContextSaveStatus -- save bits in current status */ 201*72ac97cdSTom Musta /* */ 202*72ac97cdSTom Musta /* context is the context structure to be queried */ 203*72ac97cdSTom Musta /* mask indicates the bits to be saved (the status bits that */ 204*72ac97cdSTom Musta /* correspond to each 1 bit in the mask are saved) */ 205*72ac97cdSTom Musta /* returns the AND of the mask and the current status */ 206*72ac97cdSTom Musta /* */ 207*72ac97cdSTom Musta /* No error is possible. */ 208*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 209*72ac97cdSTom Musta uInt decContextSaveStatus(decContext *context, uInt mask) { 210*72ac97cdSTom Musta return context->status&mask; 211*72ac97cdSTom Musta } /* decContextSaveStatus */ 212*72ac97cdSTom Musta 213*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 214*72ac97cdSTom Musta /* decContextSetRounding -- set current rounding mode */ 215*72ac97cdSTom Musta /* */ 216*72ac97cdSTom Musta /* context is the context structure to be updated */ 217*72ac97cdSTom Musta /* newround is the value which will replace the current mode */ 218*72ac97cdSTom Musta /* returns context */ 219*72ac97cdSTom Musta /* */ 220*72ac97cdSTom Musta /* No error is possible. */ 221*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 222*72ac97cdSTom Musta decContext *decContextSetRounding(decContext *context, 223*72ac97cdSTom Musta enum rounding newround) { 224*72ac97cdSTom Musta context->round=newround; 225*72ac97cdSTom Musta return context; 226*72ac97cdSTom Musta } /* decContextSetRounding */ 227*72ac97cdSTom Musta 228*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 229*72ac97cdSTom Musta /* decContextSetStatus -- set status and raise trap if appropriate */ 230*72ac97cdSTom Musta /* */ 231*72ac97cdSTom Musta /* context is the context structure to be updated */ 232*72ac97cdSTom Musta /* status is the DEC_ exception code */ 233*72ac97cdSTom Musta /* returns the context structure */ 234*72ac97cdSTom Musta /* */ 235*72ac97cdSTom Musta /* Control may never return from this routine, if there is a signal */ 236*72ac97cdSTom Musta /* handler and it takes a long jump. */ 237*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 238*72ac97cdSTom Musta decContext * decContextSetStatus(decContext *context, uInt status) { 239*72ac97cdSTom Musta context->status|=status; 240*72ac97cdSTom Musta if (status & context->traps) raise(SIGFPE); 241*72ac97cdSTom Musta return context;} /* decContextSetStatus */ 242*72ac97cdSTom Musta 243*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 244*72ac97cdSTom Musta /* decContextSetStatusFromString -- set status from a string + trap */ 245*72ac97cdSTom Musta /* */ 246*72ac97cdSTom Musta /* context is the context structure to be updated */ 247*72ac97cdSTom Musta /* string is a string exactly equal to one that might be returned */ 248*72ac97cdSTom Musta /* by decContextStatusToString */ 249*72ac97cdSTom Musta /* */ 250*72ac97cdSTom Musta /* The status bit corresponding to the string is set, and a trap */ 251*72ac97cdSTom Musta /* is raised if appropriate. */ 252*72ac97cdSTom Musta /* */ 253*72ac97cdSTom Musta /* returns the context structure, unless the string is equal to */ 254*72ac97cdSTom Musta /* DEC_Condition_MU or is not recognized. In these cases NULL is */ 255*72ac97cdSTom Musta /* returned. */ 256*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 257*72ac97cdSTom Musta decContext * decContextSetStatusFromString(decContext *context, 258*72ac97cdSTom Musta const char *string) { 259*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_CS)==0) 260*72ac97cdSTom Musta return decContextSetStatus(context, DEC_Conversion_syntax); 261*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_DZ)==0) 262*72ac97cdSTom Musta return decContextSetStatus(context, DEC_Division_by_zero); 263*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_DI)==0) 264*72ac97cdSTom Musta return decContextSetStatus(context, DEC_Division_impossible); 265*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_DU)==0) 266*72ac97cdSTom Musta return decContextSetStatus(context, DEC_Division_undefined); 267*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_IE)==0) 268*72ac97cdSTom Musta return decContextSetStatus(context, DEC_Inexact); 269*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_IS)==0) 270*72ac97cdSTom Musta return decContextSetStatus(context, DEC_Insufficient_storage); 271*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_IC)==0) 272*72ac97cdSTom Musta return decContextSetStatus(context, DEC_Invalid_context); 273*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_IO)==0) 274*72ac97cdSTom Musta return decContextSetStatus(context, DEC_Invalid_operation); 275*72ac97cdSTom Musta #if DECSUBSET 276*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_LD)==0) 277*72ac97cdSTom Musta return decContextSetStatus(context, DEC_Lost_digits); 278*72ac97cdSTom Musta #endif 279*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_OV)==0) 280*72ac97cdSTom Musta return decContextSetStatus(context, DEC_Overflow); 281*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_PA)==0) 282*72ac97cdSTom Musta return decContextSetStatus(context, DEC_Clamped); 283*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_RO)==0) 284*72ac97cdSTom Musta return decContextSetStatus(context, DEC_Rounded); 285*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_SU)==0) 286*72ac97cdSTom Musta return decContextSetStatus(context, DEC_Subnormal); 287*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_UN)==0) 288*72ac97cdSTom Musta return decContextSetStatus(context, DEC_Underflow); 289*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_ZE)==0) 290*72ac97cdSTom Musta return context; 291*72ac97cdSTom Musta return NULL; /* Multiple status, or unknown */ 292*72ac97cdSTom Musta } /* decContextSetStatusFromString */ 293*72ac97cdSTom Musta 294*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 295*72ac97cdSTom Musta /* decContextSetStatusFromStringQuiet -- set status from a string */ 296*72ac97cdSTom Musta /* */ 297*72ac97cdSTom Musta /* context is the context structure to be updated */ 298*72ac97cdSTom Musta /* string is a string exactly equal to one that might be returned */ 299*72ac97cdSTom Musta /* by decContextStatusToString */ 300*72ac97cdSTom Musta /* */ 301*72ac97cdSTom Musta /* The status bit corresponding to the string is set; no trap is */ 302*72ac97cdSTom Musta /* raised. */ 303*72ac97cdSTom Musta /* */ 304*72ac97cdSTom Musta /* returns the context structure, unless the string is equal to */ 305*72ac97cdSTom Musta /* DEC_Condition_MU or is not recognized. In these cases NULL is */ 306*72ac97cdSTom Musta /* returned. */ 307*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 308*72ac97cdSTom Musta decContext * decContextSetStatusFromStringQuiet(decContext *context, 309*72ac97cdSTom Musta const char *string) { 310*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_CS)==0) 311*72ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Conversion_syntax); 312*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_DZ)==0) 313*72ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Division_by_zero); 314*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_DI)==0) 315*72ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Division_impossible); 316*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_DU)==0) 317*72ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Division_undefined); 318*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_IE)==0) 319*72ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Inexact); 320*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_IS)==0) 321*72ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Insufficient_storage); 322*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_IC)==0) 323*72ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Invalid_context); 324*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_IO)==0) 325*72ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Invalid_operation); 326*72ac97cdSTom Musta #if DECSUBSET 327*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_LD)==0) 328*72ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Lost_digits); 329*72ac97cdSTom Musta #endif 330*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_OV)==0) 331*72ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Overflow); 332*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_PA)==0) 333*72ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Clamped); 334*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_RO)==0) 335*72ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Rounded); 336*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_SU)==0) 337*72ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Subnormal); 338*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_UN)==0) 339*72ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Underflow); 340*72ac97cdSTom Musta if (strcmp(string, DEC_Condition_ZE)==0) 341*72ac97cdSTom Musta return context; 342*72ac97cdSTom Musta return NULL; /* Multiple status, or unknown */ 343*72ac97cdSTom Musta } /* decContextSetStatusFromStringQuiet */ 344*72ac97cdSTom Musta 345*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 346*72ac97cdSTom Musta /* decContextSetStatusQuiet -- set status without trap */ 347*72ac97cdSTom Musta /* */ 348*72ac97cdSTom Musta /* context is the context structure to be updated */ 349*72ac97cdSTom Musta /* status is the DEC_ exception code */ 350*72ac97cdSTom Musta /* returns the context structure */ 351*72ac97cdSTom Musta /* */ 352*72ac97cdSTom Musta /* No error is possible. */ 353*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 354*72ac97cdSTom Musta decContext * decContextSetStatusQuiet(decContext *context, uInt status) { 355*72ac97cdSTom Musta context->status|=status; 356*72ac97cdSTom Musta return context;} /* decContextSetStatusQuiet */ 357*72ac97cdSTom Musta 358*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 359*72ac97cdSTom Musta /* decContextStatusToString -- convert status flags to a string */ 360*72ac97cdSTom Musta /* */ 361*72ac97cdSTom Musta /* context is a context with valid status field */ 362*72ac97cdSTom Musta /* */ 363*72ac97cdSTom Musta /* returns a constant string describing the condition. If multiple */ 364*72ac97cdSTom Musta /* (or no) flags are set, a generic constant message is returned. */ 365*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 366*72ac97cdSTom Musta const char *decContextStatusToString(const decContext *context) { 367*72ac97cdSTom Musta Int status=context->status; 368*72ac97cdSTom Musta 369*72ac97cdSTom Musta /* test the five IEEE first, as some of the others are ambiguous when */ 370*72ac97cdSTom Musta /* DECEXTFLAG=0 */ 371*72ac97cdSTom Musta if (status==DEC_Invalid_operation ) return DEC_Condition_IO; 372*72ac97cdSTom Musta if (status==DEC_Division_by_zero ) return DEC_Condition_DZ; 373*72ac97cdSTom Musta if (status==DEC_Overflow ) return DEC_Condition_OV; 374*72ac97cdSTom Musta if (status==DEC_Underflow ) return DEC_Condition_UN; 375*72ac97cdSTom Musta if (status==DEC_Inexact ) return DEC_Condition_IE; 376*72ac97cdSTom Musta 377*72ac97cdSTom Musta if (status==DEC_Division_impossible ) return DEC_Condition_DI; 378*72ac97cdSTom Musta if (status==DEC_Division_undefined ) return DEC_Condition_DU; 379*72ac97cdSTom Musta if (status==DEC_Rounded ) return DEC_Condition_RO; 380*72ac97cdSTom Musta if (status==DEC_Clamped ) return DEC_Condition_PA; 381*72ac97cdSTom Musta if (status==DEC_Subnormal ) return DEC_Condition_SU; 382*72ac97cdSTom Musta if (status==DEC_Conversion_syntax ) return DEC_Condition_CS; 383*72ac97cdSTom Musta if (status==DEC_Insufficient_storage ) return DEC_Condition_IS; 384*72ac97cdSTom Musta if (status==DEC_Invalid_context ) return DEC_Condition_IC; 385*72ac97cdSTom Musta #if DECSUBSET 386*72ac97cdSTom Musta if (status==DEC_Lost_digits ) return DEC_Condition_LD; 387*72ac97cdSTom Musta #endif 388*72ac97cdSTom Musta if (status==0 ) return DEC_Condition_ZE; 389*72ac97cdSTom Musta return DEC_Condition_MU; /* Multiple errors */ 390*72ac97cdSTom Musta } /* decContextStatusToString */ 391*72ac97cdSTom Musta 392*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 393*72ac97cdSTom Musta /* decContextTestSavedStatus -- test bits in saved status */ 394*72ac97cdSTom Musta /* */ 395*72ac97cdSTom Musta /* oldstatus is the status word to be tested */ 396*72ac97cdSTom Musta /* mask indicates the bits to be tested (the oldstatus bits that */ 397*72ac97cdSTom Musta /* correspond to each 1 bit in the mask are tested) */ 398*72ac97cdSTom Musta /* returns 1 if any of the tested bits are 1, or 0 otherwise */ 399*72ac97cdSTom Musta /* */ 400*72ac97cdSTom Musta /* No error is possible. */ 401*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 402*72ac97cdSTom Musta uInt decContextTestSavedStatus(uInt oldstatus, uInt mask) { 403*72ac97cdSTom Musta return (oldstatus&mask)!=0; 404*72ac97cdSTom Musta } /* decContextTestSavedStatus */ 405*72ac97cdSTom Musta 406*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 407*72ac97cdSTom Musta /* decContextTestStatus -- test bits in current status */ 408*72ac97cdSTom Musta /* */ 409*72ac97cdSTom Musta /* context is the context structure to be updated */ 410*72ac97cdSTom Musta /* mask indicates the bits to be tested (the status bits that */ 411*72ac97cdSTom Musta /* correspond to each 1 bit in the mask are tested) */ 412*72ac97cdSTom Musta /* returns 1 if any of the tested bits are 1, or 0 otherwise */ 413*72ac97cdSTom Musta /* */ 414*72ac97cdSTom Musta /* No error is possible. */ 415*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 416*72ac97cdSTom Musta uInt decContextTestStatus(decContext *context, uInt mask) { 417*72ac97cdSTom Musta return (context->status&mask)!=0; 418*72ac97cdSTom Musta } /* decContextTestStatus */ 419*72ac97cdSTom Musta 420*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 421*72ac97cdSTom Musta /* decContextZeroStatus -- clear all status bits */ 422*72ac97cdSTom Musta /* */ 423*72ac97cdSTom Musta /* context is the context structure to be updated */ 424*72ac97cdSTom Musta /* returns context */ 425*72ac97cdSTom Musta /* */ 426*72ac97cdSTom Musta /* No error is possible. */ 427*72ac97cdSTom Musta /* ------------------------------------------------------------------ */ 428*72ac97cdSTom Musta decContext *decContextZeroStatus(decContext *context) { 429*72ac97cdSTom Musta context->status=0; 430*72ac97cdSTom Musta return context; 431*72ac97cdSTom Musta } /* decContextZeroStatus */ 432