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