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