]> git.ipfire.org Git - thirdparty/gcc.git/blame - libdecnumber/decContext.c
Daily bump.
[thirdparty/gcc.git] / libdecnumber / decContext.c
CommitLineData
e3f15eef 1/* Decimal context module for the decNumber C Library.
2 Copyright (C) 2005 Free Software Foundation, Inc.
3 Contributed by IBM Corporation. Author Mike Cowlishaw.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA. */
21
22/* This module compirises the routines for handling the arithmetic
23 context structures. */
24
25#include <string.h> /* for strcmp */
26#include "decContext.h" /* context and base types */
27#include "decNumberLocal.h" /* decNumber local types, etc. */
28
29/* ------------------------------------------------------------------ */
30/* decContextDefault -- initialize a context structure */
31/* */
32/* context is the structure to be initialized */
33/* kind selects the required set of default values, one of: */
34/* DEC_INIT_BASE -- select ANSI X3-274 defaults */
35/* DEC_INIT_DECIMAL32 -- select IEEE 754r defaults, 32-bit */
36/* DEC_INIT_DECIMAL64 -- select IEEE 754r defaults, 64-bit */
37/* DEC_INIT_DECIMAL128 -- select IEEE 754r defaults, 128-bit */
38/* For any other value a valid context is returned, but with */
39/* Invalid_operation set in the status field. */
40/* returns a context structure with the appropriate initial values. */
41/* ------------------------------------------------------------------ */
42decContext *
43decContextDefault (decContext * context, Int kind)
44{
45 /* set defaults... */
46 context->digits = 9; /* 9 digits */
47 context->emax = DEC_MAX_EMAX; /* 9-digit exponents */
48 context->emin = DEC_MIN_EMIN; /* .. balanced */
49 context->round = DEC_ROUND_HALF_UP; /* 0.5 rises */
50 context->traps = DEC_Errors; /* all but informational */
51 context->status = 0; /* cleared */
52 context->clamp = 0; /* no clamping */
53#if DECSUBSET
54 context->extended = 0; /* cleared */
55#endif
56 switch (kind)
57 {
58 case DEC_INIT_BASE:
59 /* [use defaults] */
60 break;
61 case DEC_INIT_DECIMAL32:
62 context->digits = 7; /* digits */
63 context->emax = 96; /* Emax */
64 context->emin = -95; /* Emin */
65 context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
66 context->traps = 0; /* no traps set */
67 context->clamp = 1; /* clamp exponents */
68#if DECSUBSET
69 context->extended = 1; /* set */
70#endif
71 break;
72 case DEC_INIT_DECIMAL64:
73 context->digits = 16; /* digits */
74 context->emax = 384; /* Emax */
75 context->emin = -383; /* Emin */
76 context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
77 context->traps = 0; /* no traps set */
78 context->clamp = 1; /* clamp exponents */
79#if DECSUBSET
80 context->extended = 1; /* set */
81#endif
82 break;
83 case DEC_INIT_DECIMAL128:
84 context->digits = 34; /* digits */
85 context->emax = 6144; /* Emax */
86 context->emin = -6143; /* Emin */
87 context->round = DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
88 context->traps = 0; /* no traps set */
89 context->clamp = 1; /* clamp exponents */
90#if DECSUBSET
91 context->extended = 1; /* set */
92#endif
93 break;
94
95 default: /* invalid Kind */
96 /* use defaults, and .. */
97 decContextSetStatus (context, DEC_Invalid_operation); /* trap */
98 }
99 return context;
100} /* decContextDefault */
101
102/* ------------------------------------------------------------------ */
103/* decContextStatusToString -- convert status flags to a string */
104/* */
105/* context is a context with valid status field */
106/* */
107/* returns a constant string describing the condition. If multiple */
108/* (or no) flags are set, a generic constant message is returned. */
109/* ------------------------------------------------------------------ */
110const char *
111decContextStatusToString (decContext * context)
112{
113 Int status = context->status;
114 if (status == DEC_Conversion_syntax)
115 return DEC_Condition_CS;
116 if (status == DEC_Division_by_zero)
117 return DEC_Condition_DZ;
118 if (status == DEC_Division_impossible)
119 return DEC_Condition_DI;
120 if (status == DEC_Division_undefined)
121 return DEC_Condition_DU;
122 if (status == DEC_Inexact)
123 return DEC_Condition_IE;
124 if (status == DEC_Insufficient_storage)
125 return DEC_Condition_IS;
126 if (status == DEC_Invalid_context)
127 return DEC_Condition_IC;
128 if (status == DEC_Invalid_operation)
129 return DEC_Condition_IO;
130#if DECSUBSET
131 if (status == DEC_Lost_digits)
132 return DEC_Condition_LD;
133#endif
134 if (status == DEC_Overflow)
135 return DEC_Condition_OV;
136 if (status == DEC_Clamped)
137 return DEC_Condition_PA;
138 if (status == DEC_Rounded)
139 return DEC_Condition_RO;
140 if (status == DEC_Subnormal)
141 return DEC_Condition_SU;
142 if (status == DEC_Underflow)
143 return DEC_Condition_UN;
144 if (status == 0)
145 return DEC_Condition_ZE;
146 return DEC_Condition_MU; /* Multiple errors */
147} /* decContextStatusToString */
148
149/* ------------------------------------------------------------------ */
150/* decContextSetStatusFromString -- set status from a string */
151/* */
152/* context is the controlling context */
153/* string is a string exactly equal to one that might be returned */
154/* by decContextStatusToString */
155/* */
156/* The status bit corresponding to the string is set, and a trap */
157/* is raised if appropriate. */
158/* */
159/* returns the context structure, unless the string is equal to */
160/* DEC_Condition_MU or is not recognized. In these cases NULL is */
161/* returned. */
162/* ------------------------------------------------------------------ */
163decContext *
164decContextSetStatusFromString (decContext * context, char *string)
165{
166 if (strcmp (string, DEC_Condition_CS) == 0)
167 return decContextSetStatus (context, DEC_Conversion_syntax);
168 if (strcmp (string, DEC_Condition_DZ) == 0)
169 return decContextSetStatus (context, DEC_Division_by_zero);
170 if (strcmp (string, DEC_Condition_DI) == 0)
171 return decContextSetStatus (context, DEC_Division_impossible);
172 if (strcmp (string, DEC_Condition_DU) == 0)
173 return decContextSetStatus (context, DEC_Division_undefined);
174 if (strcmp (string, DEC_Condition_IE) == 0)
175 return decContextSetStatus (context, DEC_Inexact);
176 if (strcmp (string, DEC_Condition_IS) == 0)
177 return decContextSetStatus (context, DEC_Insufficient_storage);
178 if (strcmp (string, DEC_Condition_IC) == 0)
179 return decContextSetStatus (context, DEC_Invalid_context);
180 if (strcmp (string, DEC_Condition_IO) == 0)
181 return decContextSetStatus (context, DEC_Invalid_operation);
182#if DECSUBSET
183 if (strcmp (string, DEC_Condition_LD) == 0)
184 return decContextSetStatus (context, DEC_Lost_digits);
185#endif
186 if (strcmp (string, DEC_Condition_OV) == 0)
187 return decContextSetStatus (context, DEC_Overflow);
188 if (strcmp (string, DEC_Condition_PA) == 0)
189 return decContextSetStatus (context, DEC_Clamped);
190 if (strcmp (string, DEC_Condition_RO) == 0)
191 return decContextSetStatus (context, DEC_Rounded);
192 if (strcmp (string, DEC_Condition_SU) == 0)
193 return decContextSetStatus (context, DEC_Subnormal);
194 if (strcmp (string, DEC_Condition_UN) == 0)
195 return decContextSetStatus (context, DEC_Underflow);
196 if (strcmp (string, DEC_Condition_ZE) == 0)
197 return context;
198 return NULL; /* Multiple status, or unknown */
199} /* decContextSetStatusFromString */
200
201/* ------------------------------------------------------------------ */
202/* decContextSetStatus -- set status and raise trap if appropriate */
203/* */
204/* context is the controlling context */
205/* status is the DEC_ exception code */
206/* returns the context structure */
207/* */
208/* Control may never return from this routine, if there is a signal */
209/* handler and it takes a long jump. */
210/* ------------------------------------------------------------------ */
211decContext *
212decContextSetStatus (decContext * context, uInt status)
213{
214 context->status |= status;
215 if (status & context->traps)
216 raise (SIGFPE);
217 return context;
218} /* decContextSetStatus */