OSDN Git Service

* configure.ac (ACX_PROG_CC_WARNING_OPTS): Add -Wcast-qual.
[pf3gnuchains/gcc-fork.git] / libdecnumber / decContext.c
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, 51 Franklin Street, Fifth Floor, Boston, MA
20    02110-1301, USA.  */
21
22 /*  This module compirises the routines for handling the arithmetic
23     context structures. */
24
25 #include <string.h>             /* for strcmp */
26 #include "config.h"
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 /* ------------------------------------------------------------------ */
43 decContext *
44 decContextDefault (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 /* ------------------------------------------------------------------ */
111 const char *
112 decContextStatusToString (const 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 /* ------------------------------------------------------------------ */
164 decContext *
165 decContextSetStatusFromString (decContext * context, const 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 /* ------------------------------------------------------------------ */
212 decContext *
213 decContextSetStatus (decContext * context, uInt status)
214 {
215   context->status |= status;
216   if (status & context->traps)
217     raise (SIGFPE);
218   return context;
219 }                               /* decContextSetStatus */