172ac97cdSTom Musta /* Decimal context module for the decNumber C Library. 272ac97cdSTom Musta Copyright (C) 2005, 2007 Free Software Foundation, Inc. 372ac97cdSTom Musta Contributed by IBM Corporation. Author Mike Cowlishaw. 472ac97cdSTom Musta 572ac97cdSTom Musta This file is part of GCC. 672ac97cdSTom Musta 772ac97cdSTom Musta GCC is free software; you can redistribute it and/or modify it under 872ac97cdSTom Musta the terms of the GNU General Public License as published by the Free 972ac97cdSTom Musta Software Foundation; either version 2, or (at your option) any later 1072ac97cdSTom Musta version. 1172ac97cdSTom Musta 1272ac97cdSTom Musta In addition to the permissions in the GNU General Public License, 1372ac97cdSTom Musta the Free Software Foundation gives you unlimited permission to link 1472ac97cdSTom Musta the compiled version of this file into combinations with other 1572ac97cdSTom Musta programs, and to distribute those combinations without any 1672ac97cdSTom Musta restriction coming from the use of this file. (The General Public 1772ac97cdSTom Musta License restrictions do apply in other respects; for example, they 1872ac97cdSTom Musta cover modification of the file, and distribution when not linked 1972ac97cdSTom Musta into a combine executable.) 2072ac97cdSTom Musta 2172ac97cdSTom Musta GCC is distributed in the hope that it will be useful, but WITHOUT ANY 2272ac97cdSTom Musta WARRANTY; without even the implied warranty of MERCHANTABILITY or 2372ac97cdSTom Musta FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2472ac97cdSTom Musta for more details. 2572ac97cdSTom Musta 2672ac97cdSTom Musta You should have received a copy of the GNU General Public License 2772ac97cdSTom Musta along with GCC; see the file COPYING. If not, write to the Free 2872ac97cdSTom Musta Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 2972ac97cdSTom Musta 02110-1301, USA. */ 3072ac97cdSTom Musta 3172ac97cdSTom Musta /* ------------------------------------------------------------------ */ 3272ac97cdSTom Musta /* Decimal Context module */ 3372ac97cdSTom Musta /* ------------------------------------------------------------------ */ 3472ac97cdSTom Musta /* This module comprises the routines for handling arithmetic */ 3572ac97cdSTom Musta /* context structures. */ 3672ac97cdSTom Musta /* ------------------------------------------------------------------ */ 3772ac97cdSTom Musta 3872ac97cdSTom Musta #include <string.h> /* for strcmp */ 3972ac97cdSTom Musta #include <stdio.h> /* for printf if DECCHECK */ 40*0f2d3732STom Musta #include "libdecnumber/dconfig.h" 41*0f2d3732STom Musta #include "libdecnumber/decContext.h" 42*0f2d3732STom Musta #include "libdecnumber/decNumberLocal.h" 4372ac97cdSTom Musta 4472ac97cdSTom Musta #if DECCHECK 4572ac97cdSTom Musta /* compile-time endian tester [assumes sizeof(Int)>1] */ 4672ac97cdSTom Musta static const Int mfcone=1; /* constant 1 */ 4772ac97cdSTom Musta static const Flag *mfctop=(Flag *)&mfcone; /* -> top byte */ 4872ac97cdSTom Musta #define LITEND *mfctop /* named flag; 1=little-endian */ 4972ac97cdSTom Musta #endif 5072ac97cdSTom Musta 5172ac97cdSTom Musta /* ------------------------------------------------------------------ */ 5272ac97cdSTom Musta /* round-for-reround digits */ 5372ac97cdSTom Musta /* ------------------------------------------------------------------ */ 5472ac97cdSTom Musta const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */ 5572ac97cdSTom Musta 5672ac97cdSTom Musta /* ------------------------------------------------------------------ */ 5772ac97cdSTom Musta /* Powers of ten (powers[n]==10**n, 0<=n<=9) */ 5872ac97cdSTom Musta /* ------------------------------------------------------------------ */ 5972ac97cdSTom Musta const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000, 6072ac97cdSTom Musta 10000000, 100000000, 1000000000}; 6172ac97cdSTom Musta 6272ac97cdSTom Musta /* ------------------------------------------------------------------ */ 6372ac97cdSTom Musta /* decContextClearStatus -- clear bits in current status */ 6472ac97cdSTom Musta /* */ 6572ac97cdSTom Musta /* context is the context structure to be queried */ 6672ac97cdSTom Musta /* mask indicates the bits to be cleared (the status bit that */ 6772ac97cdSTom Musta /* corresponds to each 1 bit in the mask is cleared) */ 6872ac97cdSTom Musta /* returns context */ 6972ac97cdSTom Musta /* */ 7072ac97cdSTom Musta /* No error is possible. */ 7172ac97cdSTom Musta /* ------------------------------------------------------------------ */ 7272ac97cdSTom Musta decContext *decContextClearStatus(decContext *context, uInt mask) { 7372ac97cdSTom Musta context->status&=~mask; 7472ac97cdSTom Musta return context; 7572ac97cdSTom Musta } /* decContextClearStatus */ 7672ac97cdSTom Musta 7772ac97cdSTom Musta /* ------------------------------------------------------------------ */ 7872ac97cdSTom Musta /* decContextDefault -- initialize a context structure */ 7972ac97cdSTom Musta /* */ 8072ac97cdSTom Musta /* context is the structure to be initialized */ 8172ac97cdSTom Musta /* kind selects the required set of default values, one of: */ 8272ac97cdSTom Musta /* DEC_INIT_BASE -- select ANSI X3-274 defaults */ 8372ac97cdSTom Musta /* DEC_INIT_DECIMAL32 -- select IEEE 754r defaults, 32-bit */ 8472ac97cdSTom Musta /* DEC_INIT_DECIMAL64 -- select IEEE 754r defaults, 64-bit */ 8572ac97cdSTom Musta /* DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit */ 8672ac97cdSTom Musta /* For any other value a valid context is returned, but with */ 8772ac97cdSTom Musta /* Invalid_operation set in the status field. */ 8872ac97cdSTom Musta /* returns a context structure with the appropriate initial values. */ 8972ac97cdSTom Musta /* ------------------------------------------------------------------ */ 9072ac97cdSTom Musta decContext * decContextDefault(decContext *context, Int kind) { 9172ac97cdSTom Musta /* set defaults... */ 9272ac97cdSTom Musta context->digits=9; /* 9 digits */ 9372ac97cdSTom Musta context->emax=DEC_MAX_EMAX; /* 9-digit exponents */ 9472ac97cdSTom Musta context->emin=DEC_MIN_EMIN; /* .. balanced */ 9572ac97cdSTom Musta context->round=DEC_ROUND_HALF_UP; /* 0.5 rises */ 9672ac97cdSTom Musta context->traps=DEC_Errors; /* all but informational */ 9772ac97cdSTom Musta context->status=0; /* cleared */ 9872ac97cdSTom Musta context->clamp=0; /* no clamping */ 9972ac97cdSTom Musta #if DECSUBSET 10072ac97cdSTom Musta context->extended=0; /* cleared */ 10172ac97cdSTom Musta #endif 10272ac97cdSTom Musta switch (kind) { 10372ac97cdSTom Musta case DEC_INIT_BASE: 10472ac97cdSTom Musta /* [use defaults] */ 10572ac97cdSTom Musta break; 10672ac97cdSTom Musta case DEC_INIT_DECIMAL32: 10772ac97cdSTom Musta context->digits=7; /* digits */ 10872ac97cdSTom Musta context->emax=96; /* Emax */ 10972ac97cdSTom Musta context->emin=-95; /* Emin */ 11072ac97cdSTom Musta context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ 11172ac97cdSTom Musta context->traps=0; /* no traps set */ 11272ac97cdSTom Musta context->clamp=1; /* clamp exponents */ 11372ac97cdSTom Musta #if DECSUBSET 11472ac97cdSTom Musta context->extended=1; /* set */ 11572ac97cdSTom Musta #endif 11672ac97cdSTom Musta break; 11772ac97cdSTom Musta case DEC_INIT_DECIMAL64: 11872ac97cdSTom Musta context->digits=16; /* digits */ 11972ac97cdSTom Musta context->emax=384; /* Emax */ 12072ac97cdSTom Musta context->emin=-383; /* Emin */ 12172ac97cdSTom Musta context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ 12272ac97cdSTom Musta context->traps=0; /* no traps set */ 12372ac97cdSTom Musta context->clamp=1; /* clamp exponents */ 12472ac97cdSTom Musta #if DECSUBSET 12572ac97cdSTom Musta context->extended=1; /* set */ 12672ac97cdSTom Musta #endif 12772ac97cdSTom Musta break; 12872ac97cdSTom Musta case DEC_INIT_DECIMAL128: 12972ac97cdSTom Musta context->digits=34; /* digits */ 13072ac97cdSTom Musta context->emax=6144; /* Emax */ 13172ac97cdSTom Musta context->emin=-6143; /* Emin */ 13272ac97cdSTom Musta context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */ 13372ac97cdSTom Musta context->traps=0; /* no traps set */ 13472ac97cdSTom Musta context->clamp=1; /* clamp exponents */ 13572ac97cdSTom Musta #if DECSUBSET 13672ac97cdSTom Musta context->extended=1; /* set */ 13772ac97cdSTom Musta #endif 13872ac97cdSTom Musta break; 13972ac97cdSTom Musta 14072ac97cdSTom Musta default: /* invalid Kind */ 14172ac97cdSTom Musta /* use defaults, and .. */ 14272ac97cdSTom Musta decContextSetStatus(context, DEC_Invalid_operation); /* trap */ 14372ac97cdSTom Musta } 14472ac97cdSTom Musta 14572ac97cdSTom Musta #if DECCHECK 14672ac97cdSTom Musta if (LITEND!=DECLITEND) { 14772ac97cdSTom Musta const char *adj; 14872ac97cdSTom Musta if (LITEND) adj="little"; 14972ac97cdSTom Musta else adj="big"; 15072ac97cdSTom Musta printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n", 15172ac97cdSTom Musta DECLITEND, adj); 15272ac97cdSTom Musta } 15372ac97cdSTom Musta #endif 15472ac97cdSTom Musta return context;} /* decContextDefault */ 15572ac97cdSTom Musta 15672ac97cdSTom Musta /* ------------------------------------------------------------------ */ 15772ac97cdSTom Musta /* decContextGetRounding -- return current rounding mode */ 15872ac97cdSTom Musta /* */ 15972ac97cdSTom Musta /* context is the context structure to be queried */ 16072ac97cdSTom Musta /* returns the rounding mode */ 16172ac97cdSTom Musta /* */ 16272ac97cdSTom Musta /* No error is possible. */ 16372ac97cdSTom Musta /* ------------------------------------------------------------------ */ 16472ac97cdSTom Musta enum rounding decContextGetRounding(decContext *context) { 16572ac97cdSTom Musta return context->round; 16672ac97cdSTom Musta } /* decContextGetRounding */ 16772ac97cdSTom Musta 16872ac97cdSTom Musta /* ------------------------------------------------------------------ */ 16972ac97cdSTom Musta /* decContextGetStatus -- return current status */ 17072ac97cdSTom Musta /* */ 17172ac97cdSTom Musta /* context is the context structure to be queried */ 17272ac97cdSTom Musta /* returns status */ 17372ac97cdSTom Musta /* */ 17472ac97cdSTom Musta /* No error is possible. */ 17572ac97cdSTom Musta /* ------------------------------------------------------------------ */ 17672ac97cdSTom Musta uInt decContextGetStatus(decContext *context) { 17772ac97cdSTom Musta return context->status; 17872ac97cdSTom Musta } /* decContextGetStatus */ 17972ac97cdSTom Musta 18072ac97cdSTom Musta /* ------------------------------------------------------------------ */ 18172ac97cdSTom Musta /* decContextRestoreStatus -- restore bits in current status */ 18272ac97cdSTom Musta /* */ 18372ac97cdSTom Musta /* context is the context structure to be updated */ 18472ac97cdSTom Musta /* newstatus is the source for the bits to be restored */ 18572ac97cdSTom Musta /* mask indicates the bits to be restored (the status bit that */ 18672ac97cdSTom Musta /* corresponds to each 1 bit in the mask is set to the value of */ 18772ac97cdSTom Musta /* the correspnding bit in newstatus) */ 18872ac97cdSTom Musta /* returns context */ 18972ac97cdSTom Musta /* */ 19072ac97cdSTom Musta /* No error is possible. */ 19172ac97cdSTom Musta /* ------------------------------------------------------------------ */ 19272ac97cdSTom Musta decContext *decContextRestoreStatus(decContext *context, 19372ac97cdSTom Musta uInt newstatus, uInt mask) { 19472ac97cdSTom Musta context->status&=~mask; /* clear the selected bits */ 19572ac97cdSTom Musta context->status|=(mask&newstatus); /* or in the new bits */ 19672ac97cdSTom Musta return context; 19772ac97cdSTom Musta } /* decContextRestoreStatus */ 19872ac97cdSTom Musta 19972ac97cdSTom Musta /* ------------------------------------------------------------------ */ 20072ac97cdSTom Musta /* decContextSaveStatus -- save bits in current status */ 20172ac97cdSTom Musta /* */ 20272ac97cdSTom Musta /* context is the context structure to be queried */ 20372ac97cdSTom Musta /* mask indicates the bits to be saved (the status bits that */ 20472ac97cdSTom Musta /* correspond to each 1 bit in the mask are saved) */ 20572ac97cdSTom Musta /* returns the AND of the mask and the current status */ 20672ac97cdSTom Musta /* */ 20772ac97cdSTom Musta /* No error is possible. */ 20872ac97cdSTom Musta /* ------------------------------------------------------------------ */ 20972ac97cdSTom Musta uInt decContextSaveStatus(decContext *context, uInt mask) { 21072ac97cdSTom Musta return context->status&mask; 21172ac97cdSTom Musta } /* decContextSaveStatus */ 21272ac97cdSTom Musta 21372ac97cdSTom Musta /* ------------------------------------------------------------------ */ 21472ac97cdSTom Musta /* decContextSetRounding -- set current rounding mode */ 21572ac97cdSTom Musta /* */ 21672ac97cdSTom Musta /* context is the context structure to be updated */ 21772ac97cdSTom Musta /* newround is the value which will replace the current mode */ 21872ac97cdSTom Musta /* returns context */ 21972ac97cdSTom Musta /* */ 22072ac97cdSTom Musta /* No error is possible. */ 22172ac97cdSTom Musta /* ------------------------------------------------------------------ */ 22272ac97cdSTom Musta decContext *decContextSetRounding(decContext *context, 22372ac97cdSTom Musta enum rounding newround) { 22472ac97cdSTom Musta context->round=newround; 22572ac97cdSTom Musta return context; 22672ac97cdSTom Musta } /* decContextSetRounding */ 22772ac97cdSTom Musta 22872ac97cdSTom Musta /* ------------------------------------------------------------------ */ 22972ac97cdSTom Musta /* decContextSetStatus -- set status and raise trap if appropriate */ 23072ac97cdSTom Musta /* */ 23172ac97cdSTom Musta /* context is the context structure to be updated */ 23272ac97cdSTom Musta /* status is the DEC_ exception code */ 23372ac97cdSTom Musta /* returns the context structure */ 23472ac97cdSTom Musta /* */ 23572ac97cdSTom Musta /* Control may never return from this routine, if there is a signal */ 23672ac97cdSTom Musta /* handler and it takes a long jump. */ 23772ac97cdSTom Musta /* ------------------------------------------------------------------ */ 23872ac97cdSTom Musta decContext * decContextSetStatus(decContext *context, uInt status) { 23972ac97cdSTom Musta context->status|=status; 24072ac97cdSTom Musta if (status & context->traps) raise(SIGFPE); 24172ac97cdSTom Musta return context;} /* decContextSetStatus */ 24272ac97cdSTom Musta 24372ac97cdSTom Musta /* ------------------------------------------------------------------ */ 24472ac97cdSTom Musta /* decContextSetStatusFromString -- set status from a string + trap */ 24572ac97cdSTom Musta /* */ 24672ac97cdSTom Musta /* context is the context structure to be updated */ 24772ac97cdSTom Musta /* string is a string exactly equal to one that might be returned */ 24872ac97cdSTom Musta /* by decContextStatusToString */ 24972ac97cdSTom Musta /* */ 25072ac97cdSTom Musta /* The status bit corresponding to the string is set, and a trap */ 25172ac97cdSTom Musta /* is raised if appropriate. */ 25272ac97cdSTom Musta /* */ 25372ac97cdSTom Musta /* returns the context structure, unless the string is equal to */ 25472ac97cdSTom Musta /* DEC_Condition_MU or is not recognized. In these cases NULL is */ 25572ac97cdSTom Musta /* returned. */ 25672ac97cdSTom Musta /* ------------------------------------------------------------------ */ 25772ac97cdSTom Musta decContext * decContextSetStatusFromString(decContext *context, 25872ac97cdSTom Musta const char *string) { 25972ac97cdSTom Musta if (strcmp(string, DEC_Condition_CS)==0) 26072ac97cdSTom Musta return decContextSetStatus(context, DEC_Conversion_syntax); 26172ac97cdSTom Musta if (strcmp(string, DEC_Condition_DZ)==0) 26272ac97cdSTom Musta return decContextSetStatus(context, DEC_Division_by_zero); 26372ac97cdSTom Musta if (strcmp(string, DEC_Condition_DI)==0) 26472ac97cdSTom Musta return decContextSetStatus(context, DEC_Division_impossible); 26572ac97cdSTom Musta if (strcmp(string, DEC_Condition_DU)==0) 26672ac97cdSTom Musta return decContextSetStatus(context, DEC_Division_undefined); 26772ac97cdSTom Musta if (strcmp(string, DEC_Condition_IE)==0) 26872ac97cdSTom Musta return decContextSetStatus(context, DEC_Inexact); 26972ac97cdSTom Musta if (strcmp(string, DEC_Condition_IS)==0) 27072ac97cdSTom Musta return decContextSetStatus(context, DEC_Insufficient_storage); 27172ac97cdSTom Musta if (strcmp(string, DEC_Condition_IC)==0) 27272ac97cdSTom Musta return decContextSetStatus(context, DEC_Invalid_context); 27372ac97cdSTom Musta if (strcmp(string, DEC_Condition_IO)==0) 27472ac97cdSTom Musta return decContextSetStatus(context, DEC_Invalid_operation); 27572ac97cdSTom Musta #if DECSUBSET 27672ac97cdSTom Musta if (strcmp(string, DEC_Condition_LD)==0) 27772ac97cdSTom Musta return decContextSetStatus(context, DEC_Lost_digits); 27872ac97cdSTom Musta #endif 27972ac97cdSTom Musta if (strcmp(string, DEC_Condition_OV)==0) 28072ac97cdSTom Musta return decContextSetStatus(context, DEC_Overflow); 28172ac97cdSTom Musta if (strcmp(string, DEC_Condition_PA)==0) 28272ac97cdSTom Musta return decContextSetStatus(context, DEC_Clamped); 28372ac97cdSTom Musta if (strcmp(string, DEC_Condition_RO)==0) 28472ac97cdSTom Musta return decContextSetStatus(context, DEC_Rounded); 28572ac97cdSTom Musta if (strcmp(string, DEC_Condition_SU)==0) 28672ac97cdSTom Musta return decContextSetStatus(context, DEC_Subnormal); 28772ac97cdSTom Musta if (strcmp(string, DEC_Condition_UN)==0) 28872ac97cdSTom Musta return decContextSetStatus(context, DEC_Underflow); 28972ac97cdSTom Musta if (strcmp(string, DEC_Condition_ZE)==0) 29072ac97cdSTom Musta return context; 29172ac97cdSTom Musta return NULL; /* Multiple status, or unknown */ 29272ac97cdSTom Musta } /* decContextSetStatusFromString */ 29372ac97cdSTom Musta 29472ac97cdSTom Musta /* ------------------------------------------------------------------ */ 29572ac97cdSTom Musta /* decContextSetStatusFromStringQuiet -- set status from a string */ 29672ac97cdSTom Musta /* */ 29772ac97cdSTom Musta /* context is the context structure to be updated */ 29872ac97cdSTom Musta /* string is a string exactly equal to one that might be returned */ 29972ac97cdSTom Musta /* by decContextStatusToString */ 30072ac97cdSTom Musta /* */ 30172ac97cdSTom Musta /* The status bit corresponding to the string is set; no trap is */ 30272ac97cdSTom Musta /* raised. */ 30372ac97cdSTom Musta /* */ 30472ac97cdSTom Musta /* returns the context structure, unless the string is equal to */ 30572ac97cdSTom Musta /* DEC_Condition_MU or is not recognized. In these cases NULL is */ 30672ac97cdSTom Musta /* returned. */ 30772ac97cdSTom Musta /* ------------------------------------------------------------------ */ 30872ac97cdSTom Musta decContext * decContextSetStatusFromStringQuiet(decContext *context, 30972ac97cdSTom Musta const char *string) { 31072ac97cdSTom Musta if (strcmp(string, DEC_Condition_CS)==0) 31172ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Conversion_syntax); 31272ac97cdSTom Musta if (strcmp(string, DEC_Condition_DZ)==0) 31372ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Division_by_zero); 31472ac97cdSTom Musta if (strcmp(string, DEC_Condition_DI)==0) 31572ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Division_impossible); 31672ac97cdSTom Musta if (strcmp(string, DEC_Condition_DU)==0) 31772ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Division_undefined); 31872ac97cdSTom Musta if (strcmp(string, DEC_Condition_IE)==0) 31972ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Inexact); 32072ac97cdSTom Musta if (strcmp(string, DEC_Condition_IS)==0) 32172ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Insufficient_storage); 32272ac97cdSTom Musta if (strcmp(string, DEC_Condition_IC)==0) 32372ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Invalid_context); 32472ac97cdSTom Musta if (strcmp(string, DEC_Condition_IO)==0) 32572ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Invalid_operation); 32672ac97cdSTom Musta #if DECSUBSET 32772ac97cdSTom Musta if (strcmp(string, DEC_Condition_LD)==0) 32872ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Lost_digits); 32972ac97cdSTom Musta #endif 33072ac97cdSTom Musta if (strcmp(string, DEC_Condition_OV)==0) 33172ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Overflow); 33272ac97cdSTom Musta if (strcmp(string, DEC_Condition_PA)==0) 33372ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Clamped); 33472ac97cdSTom Musta if (strcmp(string, DEC_Condition_RO)==0) 33572ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Rounded); 33672ac97cdSTom Musta if (strcmp(string, DEC_Condition_SU)==0) 33772ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Subnormal); 33872ac97cdSTom Musta if (strcmp(string, DEC_Condition_UN)==0) 33972ac97cdSTom Musta return decContextSetStatusQuiet(context, DEC_Underflow); 34072ac97cdSTom Musta if (strcmp(string, DEC_Condition_ZE)==0) 34172ac97cdSTom Musta return context; 34272ac97cdSTom Musta return NULL; /* Multiple status, or unknown */ 34372ac97cdSTom Musta } /* decContextSetStatusFromStringQuiet */ 34472ac97cdSTom Musta 34572ac97cdSTom Musta /* ------------------------------------------------------------------ */ 34672ac97cdSTom Musta /* decContextSetStatusQuiet -- set status without trap */ 34772ac97cdSTom Musta /* */ 34872ac97cdSTom Musta /* context is the context structure to be updated */ 34972ac97cdSTom Musta /* status is the DEC_ exception code */ 35072ac97cdSTom Musta /* returns the context structure */ 35172ac97cdSTom Musta /* */ 35272ac97cdSTom Musta /* No error is possible. */ 35372ac97cdSTom Musta /* ------------------------------------------------------------------ */ 35472ac97cdSTom Musta decContext * decContextSetStatusQuiet(decContext *context, uInt status) { 35572ac97cdSTom Musta context->status|=status; 35672ac97cdSTom Musta return context;} /* decContextSetStatusQuiet */ 35772ac97cdSTom Musta 35872ac97cdSTom Musta /* ------------------------------------------------------------------ */ 35972ac97cdSTom Musta /* decContextStatusToString -- convert status flags to a string */ 36072ac97cdSTom Musta /* */ 36172ac97cdSTom Musta /* context is a context with valid status field */ 36272ac97cdSTom Musta /* */ 36372ac97cdSTom Musta /* returns a constant string describing the condition. If multiple */ 36472ac97cdSTom Musta /* (or no) flags are set, a generic constant message is returned. */ 36572ac97cdSTom Musta /* ------------------------------------------------------------------ */ 36672ac97cdSTom Musta const char *decContextStatusToString(const decContext *context) { 36772ac97cdSTom Musta Int status=context->status; 36872ac97cdSTom Musta 36972ac97cdSTom Musta /* test the five IEEE first, as some of the others are ambiguous when */ 37072ac97cdSTom Musta /* DECEXTFLAG=0 */ 37172ac97cdSTom Musta if (status==DEC_Invalid_operation ) return DEC_Condition_IO; 37272ac97cdSTom Musta if (status==DEC_Division_by_zero ) return DEC_Condition_DZ; 37372ac97cdSTom Musta if (status==DEC_Overflow ) return DEC_Condition_OV; 37472ac97cdSTom Musta if (status==DEC_Underflow ) return DEC_Condition_UN; 37572ac97cdSTom Musta if (status==DEC_Inexact ) return DEC_Condition_IE; 37672ac97cdSTom Musta 37772ac97cdSTom Musta if (status==DEC_Division_impossible ) return DEC_Condition_DI; 37872ac97cdSTom Musta if (status==DEC_Division_undefined ) return DEC_Condition_DU; 37972ac97cdSTom Musta if (status==DEC_Rounded ) return DEC_Condition_RO; 38072ac97cdSTom Musta if (status==DEC_Clamped ) return DEC_Condition_PA; 38172ac97cdSTom Musta if (status==DEC_Subnormal ) return DEC_Condition_SU; 38272ac97cdSTom Musta if (status==DEC_Conversion_syntax ) return DEC_Condition_CS; 38372ac97cdSTom Musta if (status==DEC_Insufficient_storage ) return DEC_Condition_IS; 38472ac97cdSTom Musta if (status==DEC_Invalid_context ) return DEC_Condition_IC; 38572ac97cdSTom Musta #if DECSUBSET 38672ac97cdSTom Musta if (status==DEC_Lost_digits ) return DEC_Condition_LD; 38772ac97cdSTom Musta #endif 38872ac97cdSTom Musta if (status==0 ) return DEC_Condition_ZE; 38972ac97cdSTom Musta return DEC_Condition_MU; /* Multiple errors */ 39072ac97cdSTom Musta } /* decContextStatusToString */ 39172ac97cdSTom Musta 39272ac97cdSTom Musta /* ------------------------------------------------------------------ */ 39372ac97cdSTom Musta /* decContextTestSavedStatus -- test bits in saved status */ 39472ac97cdSTom Musta /* */ 39572ac97cdSTom Musta /* oldstatus is the status word to be tested */ 39672ac97cdSTom Musta /* mask indicates the bits to be tested (the oldstatus bits that */ 39772ac97cdSTom Musta /* correspond to each 1 bit in the mask are tested) */ 39872ac97cdSTom Musta /* returns 1 if any of the tested bits are 1, or 0 otherwise */ 39972ac97cdSTom Musta /* */ 40072ac97cdSTom Musta /* No error is possible. */ 40172ac97cdSTom Musta /* ------------------------------------------------------------------ */ 40272ac97cdSTom Musta uInt decContextTestSavedStatus(uInt oldstatus, uInt mask) { 40372ac97cdSTom Musta return (oldstatus&mask)!=0; 40472ac97cdSTom Musta } /* decContextTestSavedStatus */ 40572ac97cdSTom Musta 40672ac97cdSTom Musta /* ------------------------------------------------------------------ */ 40772ac97cdSTom Musta /* decContextTestStatus -- test bits in current status */ 40872ac97cdSTom Musta /* */ 40972ac97cdSTom Musta /* context is the context structure to be updated */ 41072ac97cdSTom Musta /* mask indicates the bits to be tested (the status bits that */ 41172ac97cdSTom Musta /* correspond to each 1 bit in the mask are tested) */ 41272ac97cdSTom Musta /* returns 1 if any of the tested bits are 1, or 0 otherwise */ 41372ac97cdSTom Musta /* */ 41472ac97cdSTom Musta /* No error is possible. */ 41572ac97cdSTom Musta /* ------------------------------------------------------------------ */ 41672ac97cdSTom Musta uInt decContextTestStatus(decContext *context, uInt mask) { 41772ac97cdSTom Musta return (context->status&mask)!=0; 41872ac97cdSTom Musta } /* decContextTestStatus */ 41972ac97cdSTom Musta 42072ac97cdSTom Musta /* ------------------------------------------------------------------ */ 42172ac97cdSTom Musta /* decContextZeroStatus -- clear all status bits */ 42272ac97cdSTom Musta /* */ 42372ac97cdSTom Musta /* context is the context structure to be updated */ 42472ac97cdSTom Musta /* returns context */ 42572ac97cdSTom Musta /* */ 42672ac97cdSTom Musta /* No error is possible. */ 42772ac97cdSTom Musta /* ------------------------------------------------------------------ */ 42872ac97cdSTom Musta decContext *decContextZeroStatus(decContext *context) { 42972ac97cdSTom Musta context->status=0; 43072ac97cdSTom Musta return context; 43172ac97cdSTom Musta } /* decContextZeroStatus */ 432