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