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.
5 This file is part of GCC.
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
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
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, 51 Franklin Street, Fifth Floor, Boston, MA
22 /* This module compirises the routines for handling the arithmetic
23 context structures. */
25 #include <string.h> /* for strcmp */
27 #include "decContext.h" /* context and base types */
28 #include "decNumberLocal.h" /* decNumber local types, etc. */
30 /* ------------------------------------------------------------------ */
31 /* decContextDefault -- initialize a context structure */
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 /* ------------------------------------------------------------------ */
44 decContextDefault (decContext
* context
, Int kind
)
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 */
55 context
->extended
= 0; /* cleared */
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 */
70 context
->extended
= 1; /* set */
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 */
81 context
->extended
= 1; /* set */
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 */
92 context
->extended
= 1; /* set */
96 default: /* invalid Kind */
97 /* use defaults, and .. */
98 decContextSetStatus (context
, DEC_Invalid_operation
); /* trap */
101 } /* decContextDefault */
103 /* ------------------------------------------------------------------ */
104 /* decContextStatusToString -- convert status flags to a string */
106 /* context is a context with valid status field */
108 /* returns a constant string describing the condition. If multiple */
109 /* (or no) flags are set, a generic constant message is returned. */
110 /* ------------------------------------------------------------------ */
112 decContextStatusToString (decContext
* context
)
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
;
132 if (status
== DEC_Lost_digits
)
133 return DEC_Condition_LD
;
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
;
146 return DEC_Condition_ZE
;
147 return DEC_Condition_MU
; /* Multiple errors */
148 } /* decContextStatusToString */
150 /* ------------------------------------------------------------------ */
151 /* decContextSetStatusFromString -- set status from a string */
153 /* context is the controlling context */
154 /* string is a string exactly equal to one that might be returned */
155 /* by decContextStatusToString */
157 /* The status bit corresponding to the string is set, and a trap */
158 /* is raised if appropriate. */
160 /* returns the context structure, unless the string is equal to */
161 /* DEC_Condition_MU or is not recognized. In these cases NULL is */
163 /* ------------------------------------------------------------------ */
165 decContextSetStatusFromString (decContext
* context
, const char *string
)
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
);
184 if (strcmp (string
, DEC_Condition_LD
) == 0)
185 return decContextSetStatus (context
, DEC_Lost_digits
);
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)
199 return NULL
; /* Multiple status, or unknown */
200 } /* decContextSetStatusFromString */
202 /* ------------------------------------------------------------------ */
203 /* decContextSetStatus -- set status and raise trap if appropriate */
205 /* context is the controlling context */
206 /* status is the DEC_ exception code */
207 /* returns the context structure */
209 /* Control may never return from this routine, if there is a signal */
210 /* handler and it takes a long jump. */
211 /* ------------------------------------------------------------------ */
213 decContextSetStatus (decContext
* context
, uInt status
)
215 context
->status
|= status
;
216 if (status
& context
->traps
)
219 } /* decContextSetStatus */