14e98e3e1Schristos /* Decimal context module for the decNumber C Library.
2*4559860eSchristos Copyright (C) 2005-2018 Free Software Foundation, Inc.
34e98e3e1Schristos Contributed by IBM Corporation. Author Mike Cowlishaw.
44e98e3e1Schristos
54e98e3e1Schristos This file is part of GCC.
64e98e3e1Schristos
74e98e3e1Schristos GCC is free software; you can redistribute it and/or modify it under
84e98e3e1Schristos the terms of the GNU General Public License as published by the Free
94e98e3e1Schristos Software Foundation; either version 3, or (at your option) any later
104e98e3e1Schristos version.
114e98e3e1Schristos
124e98e3e1Schristos GCC is distributed in the hope that it will be useful, but WITHOUT ANY
134e98e3e1Schristos WARRANTY; without even the implied warranty of MERCHANTABILITY or
144e98e3e1Schristos FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
154e98e3e1Schristos for more details.
164e98e3e1Schristos
174e98e3e1Schristos Under Section 7 of GPL version 3, you are granted additional
184e98e3e1Schristos permissions described in the GCC Runtime Library Exception, version
194e98e3e1Schristos 3.1, as published by the Free Software Foundation.
204e98e3e1Schristos
214e98e3e1Schristos You should have received a copy of the GNU General Public License and
224e98e3e1Schristos a copy of the GCC Runtime Library Exception along with this program;
234e98e3e1Schristos see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
244e98e3e1Schristos <http://www.gnu.org/licenses/>. */
254e98e3e1Schristos
264e98e3e1Schristos /* ------------------------------------------------------------------ */
274e98e3e1Schristos /* Decimal Context module */
284e98e3e1Schristos /* ------------------------------------------------------------------ */
294e98e3e1Schristos /* This module comprises the routines for handling arithmetic */
304e98e3e1Schristos /* context structures. */
314e98e3e1Schristos /* ------------------------------------------------------------------ */
324e98e3e1Schristos
334e98e3e1Schristos #include <string.h> /* for strcmp */
344e98e3e1Schristos #ifdef DECCHECK
354e98e3e1Schristos #include <stdio.h> /* for printf if DECCHECK */
364e98e3e1Schristos #endif
374e98e3e1Schristos #include "dconfig.h" /* for GCC definitions */
384e98e3e1Schristos #include "decContext.h" /* context and base types */
394e98e3e1Schristos #include "decNumberLocal.h" /* decNumber local types, etc. */
404e98e3e1Schristos
414e98e3e1Schristos /* compile-time endian tester [assumes sizeof(Int)>1] */
424e98e3e1Schristos static const Int mfcone=1; /* constant 1 */
434e98e3e1Schristos static const Flag *mfctop=(const Flag *)&mfcone; /* -> top byte */
444e98e3e1Schristos #define LITEND *mfctop /* named flag; 1=little-endian */
454e98e3e1Schristos
464e98e3e1Schristos /* ------------------------------------------------------------------ */
474e98e3e1Schristos /* round-for-reround digits */
484e98e3e1Schristos /* ------------------------------------------------------------------ */
494e98e3e1Schristos const uByte DECSTICKYTAB[10]={1,1,2,3,4,6,6,7,8,9}; /* used if sticky */
504e98e3e1Schristos
514e98e3e1Schristos /* ------------------------------------------------------------------ */
524e98e3e1Schristos /* Powers of ten (powers[n]==10**n, 0<=n<=9) */
534e98e3e1Schristos /* ------------------------------------------------------------------ */
544e98e3e1Schristos const uInt DECPOWERS[10]={1, 10, 100, 1000, 10000, 100000, 1000000,
554e98e3e1Schristos 10000000, 100000000, 1000000000};
564e98e3e1Schristos
574e98e3e1Schristos /* ------------------------------------------------------------------ */
584e98e3e1Schristos /* decContextClearStatus -- clear bits in current status */
594e98e3e1Schristos /* */
604e98e3e1Schristos /* context is the context structure to be queried */
614e98e3e1Schristos /* mask indicates the bits to be cleared (the status bit that */
624e98e3e1Schristos /* corresponds to each 1 bit in the mask is cleared) */
634e98e3e1Schristos /* returns context */
644e98e3e1Schristos /* */
654e98e3e1Schristos /* No error is possible. */
664e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextClearStatus(decContext * context,uInt mask)674e98e3e1Schristos decContext *decContextClearStatus(decContext *context, uInt mask) {
684e98e3e1Schristos context->status&=~mask;
694e98e3e1Schristos return context;
704e98e3e1Schristos } /* decContextClearStatus */
714e98e3e1Schristos
724e98e3e1Schristos /* ------------------------------------------------------------------ */
734e98e3e1Schristos /* decContextDefault -- initialize a context structure */
744e98e3e1Schristos /* */
754e98e3e1Schristos /* context is the structure to be initialized */
764e98e3e1Schristos /* kind selects the required set of default values, one of: */
774e98e3e1Schristos /* DEC_INIT_BASE -- select ANSI X3-274 defaults */
784e98e3e1Schristos /* DEC_INIT_DECIMAL32 -- select IEEE 754 defaults, 32-bit */
794e98e3e1Schristos /* DEC_INIT_DECIMAL64 -- select IEEE 754 defaults, 64-bit */
804e98e3e1Schristos /* DEC_INIT_DECIMAL128 -- select IEEE 754 defaults, 128-bit */
814e98e3e1Schristos /* For any other value a valid context is returned, but with */
824e98e3e1Schristos /* Invalid_operation set in the status field. */
834e98e3e1Schristos /* returns a context structure with the appropriate initial values. */
844e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextDefault(decContext * context,Int kind)854e98e3e1Schristos decContext * decContextDefault(decContext *context, Int kind) {
864e98e3e1Schristos /* set defaults... */
874e98e3e1Schristos context->digits=9; /* 9 digits */
884e98e3e1Schristos context->emax=DEC_MAX_EMAX; /* 9-digit exponents */
894e98e3e1Schristos context->emin=DEC_MIN_EMIN; /* .. balanced */
904e98e3e1Schristos context->round=DEC_ROUND_HALF_UP; /* 0.5 rises */
914e98e3e1Schristos context->traps=DEC_Errors; /* all but informational */
924e98e3e1Schristos context->status=0; /* cleared */
934e98e3e1Schristos context->clamp=0; /* no clamping */
944e98e3e1Schristos #if DECSUBSET
954e98e3e1Schristos context->extended=0; /* cleared */
964e98e3e1Schristos #endif
974e98e3e1Schristos switch (kind) {
984e98e3e1Schristos case DEC_INIT_BASE:
994e98e3e1Schristos /* [use defaults] */
1004e98e3e1Schristos break;
1014e98e3e1Schristos case DEC_INIT_DECIMAL32:
1024e98e3e1Schristos context->digits=7; /* digits */
1034e98e3e1Schristos context->emax=96; /* Emax */
1044e98e3e1Schristos context->emin=-95; /* Emin */
1054e98e3e1Schristos context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
1064e98e3e1Schristos context->traps=0; /* no traps set */
1074e98e3e1Schristos context->clamp=1; /* clamp exponents */
1084e98e3e1Schristos #if DECSUBSET
1094e98e3e1Schristos context->extended=1; /* set */
1104e98e3e1Schristos #endif
1114e98e3e1Schristos break;
1124e98e3e1Schristos case DEC_INIT_DECIMAL64:
1134e98e3e1Schristos context->digits=16; /* digits */
1144e98e3e1Schristos context->emax=384; /* Emax */
1154e98e3e1Schristos context->emin=-383; /* Emin */
1164e98e3e1Schristos context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
1174e98e3e1Schristos context->traps=0; /* no traps set */
1184e98e3e1Schristos context->clamp=1; /* clamp exponents */
1194e98e3e1Schristos #if DECSUBSET
1204e98e3e1Schristos context->extended=1; /* set */
1214e98e3e1Schristos #endif
1224e98e3e1Schristos break;
1234e98e3e1Schristos case DEC_INIT_DECIMAL128:
1244e98e3e1Schristos context->digits=34; /* digits */
1254e98e3e1Schristos context->emax=6144; /* Emax */
1264e98e3e1Schristos context->emin=-6143; /* Emin */
1274e98e3e1Schristos context->round=DEC_ROUND_HALF_EVEN; /* 0.5 to nearest even */
1284e98e3e1Schristos context->traps=0; /* no traps set */
1294e98e3e1Schristos context->clamp=1; /* clamp exponents */
1304e98e3e1Schristos #if DECSUBSET
1314e98e3e1Schristos context->extended=1; /* set */
1324e98e3e1Schristos #endif
1334e98e3e1Schristos break;
1344e98e3e1Schristos
1354e98e3e1Schristos default: /* invalid Kind */
1364e98e3e1Schristos /* use defaults, and .. */
1374e98e3e1Schristos decContextSetStatus(context, DEC_Invalid_operation); /* trap */
1384e98e3e1Schristos }
1394e98e3e1Schristos
1404e98e3e1Schristos return context;} /* decContextDefault */
1414e98e3e1Schristos
1424e98e3e1Schristos /* ------------------------------------------------------------------ */
1434e98e3e1Schristos /* decContextGetRounding -- return current rounding mode */
1444e98e3e1Schristos /* */
1454e98e3e1Schristos /* context is the context structure to be queried */
1464e98e3e1Schristos /* returns the rounding mode */
1474e98e3e1Schristos /* */
1484e98e3e1Schristos /* No error is possible. */
1494e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextGetRounding(decContext * context)1504e98e3e1Schristos enum rounding decContextGetRounding(decContext *context) {
1514e98e3e1Schristos return context->round;
1524e98e3e1Schristos } /* decContextGetRounding */
1534e98e3e1Schristos
1544e98e3e1Schristos /* ------------------------------------------------------------------ */
1554e98e3e1Schristos /* decContextGetStatus -- return current status */
1564e98e3e1Schristos /* */
1574e98e3e1Schristos /* context is the context structure to be queried */
1584e98e3e1Schristos /* returns status */
1594e98e3e1Schristos /* */
1604e98e3e1Schristos /* No error is possible. */
1614e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextGetStatus(decContext * context)1624e98e3e1Schristos uInt decContextGetStatus(decContext *context) {
1634e98e3e1Schristos return context->status;
1644e98e3e1Schristos } /* decContextGetStatus */
1654e98e3e1Schristos
1664e98e3e1Schristos /* ------------------------------------------------------------------ */
1674e98e3e1Schristos /* decContextRestoreStatus -- restore bits in current status */
1684e98e3e1Schristos /* */
1694e98e3e1Schristos /* context is the context structure to be updated */
1704e98e3e1Schristos /* newstatus is the source for the bits to be restored */
1714e98e3e1Schristos /* mask indicates the bits to be restored (the status bit that */
1724e98e3e1Schristos /* corresponds to each 1 bit in the mask is set to the value of */
1734e98e3e1Schristos /* the correspnding bit in newstatus) */
1744e98e3e1Schristos /* returns context */
1754e98e3e1Schristos /* */
1764e98e3e1Schristos /* No error is possible. */
1774e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextRestoreStatus(decContext * context,uInt newstatus,uInt mask)1784e98e3e1Schristos decContext *decContextRestoreStatus(decContext *context,
1794e98e3e1Schristos uInt newstatus, uInt mask) {
1804e98e3e1Schristos context->status&=~mask; /* clear the selected bits */
1814e98e3e1Schristos context->status|=(mask&newstatus); /* or in the new bits */
1824e98e3e1Schristos return context;
1834e98e3e1Schristos } /* decContextRestoreStatus */
1844e98e3e1Schristos
1854e98e3e1Schristos /* ------------------------------------------------------------------ */
1864e98e3e1Schristos /* decContextSaveStatus -- save bits in current status */
1874e98e3e1Schristos /* */
1884e98e3e1Schristos /* context is the context structure to be queried */
1894e98e3e1Schristos /* mask indicates the bits to be saved (the status bits that */
1904e98e3e1Schristos /* correspond to each 1 bit in the mask are saved) */
1914e98e3e1Schristos /* returns the AND of the mask and the current status */
1924e98e3e1Schristos /* */
1934e98e3e1Schristos /* No error is possible. */
1944e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextSaveStatus(decContext * context,uInt mask)1954e98e3e1Schristos uInt decContextSaveStatus(decContext *context, uInt mask) {
1964e98e3e1Schristos return context->status&mask;
1974e98e3e1Schristos } /* decContextSaveStatus */
1984e98e3e1Schristos
1994e98e3e1Schristos /* ------------------------------------------------------------------ */
2004e98e3e1Schristos /* decContextSetRounding -- set current rounding mode */
2014e98e3e1Schristos /* */
2024e98e3e1Schristos /* context is the context structure to be updated */
2034e98e3e1Schristos /* newround is the value which will replace the current mode */
2044e98e3e1Schristos /* returns context */
2054e98e3e1Schristos /* */
2064e98e3e1Schristos /* No error is possible. */
2074e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextSetRounding(decContext * context,enum rounding newround)2084e98e3e1Schristos decContext *decContextSetRounding(decContext *context,
2094e98e3e1Schristos enum rounding newround) {
2104e98e3e1Schristos context->round=newround;
2114e98e3e1Schristos return context;
2124e98e3e1Schristos } /* decContextSetRounding */
2134e98e3e1Schristos
2144e98e3e1Schristos /* ------------------------------------------------------------------ */
2154e98e3e1Schristos /* decContextSetStatus -- set status and raise trap if appropriate */
2164e98e3e1Schristos /* */
2174e98e3e1Schristos /* context is the context structure to be updated */
2184e98e3e1Schristos /* status is the DEC_ exception code */
2194e98e3e1Schristos /* returns the context structure */
2204e98e3e1Schristos /* */
2214e98e3e1Schristos /* Control may never return from this routine, if there is a signal */
2224e98e3e1Schristos /* handler and it takes a long jump. */
2234e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextSetStatus(decContext * context,uInt status)2244e98e3e1Schristos decContext * decContextSetStatus(decContext *context, uInt status) {
2254e98e3e1Schristos context->status|=status;
2264e98e3e1Schristos if (status & context->traps) raise(SIGFPE);
2274e98e3e1Schristos return context;} /* decContextSetStatus */
2284e98e3e1Schristos
2294e98e3e1Schristos /* ------------------------------------------------------------------ */
2304e98e3e1Schristos /* decContextSetStatusFromString -- set status from a string + trap */
2314e98e3e1Schristos /* */
2324e98e3e1Schristos /* context is the context structure to be updated */
2334e98e3e1Schristos /* string is a string exactly equal to one that might be returned */
2344e98e3e1Schristos /* by decContextStatusToString */
2354e98e3e1Schristos /* */
2364e98e3e1Schristos /* The status bit corresponding to the string is set, and a trap */
2374e98e3e1Schristos /* is raised if appropriate. */
2384e98e3e1Schristos /* */
2394e98e3e1Schristos /* returns the context structure, unless the string is equal to */
2404e98e3e1Schristos /* DEC_Condition_MU or is not recognized. In these cases NULL is */
2414e98e3e1Schristos /* returned. */
2424e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextSetStatusFromString(decContext * context,const char * string)2434e98e3e1Schristos decContext * decContextSetStatusFromString(decContext *context,
2444e98e3e1Schristos const char *string) {
2454e98e3e1Schristos if (strcmp(string, DEC_Condition_CS)==0)
2464e98e3e1Schristos return decContextSetStatus(context, DEC_Conversion_syntax);
2474e98e3e1Schristos if (strcmp(string, DEC_Condition_DZ)==0)
2484e98e3e1Schristos return decContextSetStatus(context, DEC_Division_by_zero);
2494e98e3e1Schristos if (strcmp(string, DEC_Condition_DI)==0)
2504e98e3e1Schristos return decContextSetStatus(context, DEC_Division_impossible);
2514e98e3e1Schristos if (strcmp(string, DEC_Condition_DU)==0)
2524e98e3e1Schristos return decContextSetStatus(context, DEC_Division_undefined);
2534e98e3e1Schristos if (strcmp(string, DEC_Condition_IE)==0)
2544e98e3e1Schristos return decContextSetStatus(context, DEC_Inexact);
2554e98e3e1Schristos if (strcmp(string, DEC_Condition_IS)==0)
2564e98e3e1Schristos return decContextSetStatus(context, DEC_Insufficient_storage);
2574e98e3e1Schristos if (strcmp(string, DEC_Condition_IC)==0)
2584e98e3e1Schristos return decContextSetStatus(context, DEC_Invalid_context);
2594e98e3e1Schristos if (strcmp(string, DEC_Condition_IO)==0)
2604e98e3e1Schristos return decContextSetStatus(context, DEC_Invalid_operation);
2614e98e3e1Schristos #if DECSUBSET
2624e98e3e1Schristos if (strcmp(string, DEC_Condition_LD)==0)
2634e98e3e1Schristos return decContextSetStatus(context, DEC_Lost_digits);
2644e98e3e1Schristos #endif
2654e98e3e1Schristos if (strcmp(string, DEC_Condition_OV)==0)
2664e98e3e1Schristos return decContextSetStatus(context, DEC_Overflow);
2674e98e3e1Schristos if (strcmp(string, DEC_Condition_PA)==0)
2684e98e3e1Schristos return decContextSetStatus(context, DEC_Clamped);
2694e98e3e1Schristos if (strcmp(string, DEC_Condition_RO)==0)
2704e98e3e1Schristos return decContextSetStatus(context, DEC_Rounded);
2714e98e3e1Schristos if (strcmp(string, DEC_Condition_SU)==0)
2724e98e3e1Schristos return decContextSetStatus(context, DEC_Subnormal);
2734e98e3e1Schristos if (strcmp(string, DEC_Condition_UN)==0)
2744e98e3e1Schristos return decContextSetStatus(context, DEC_Underflow);
2754e98e3e1Schristos if (strcmp(string, DEC_Condition_ZE)==0)
2764e98e3e1Schristos return context;
2774e98e3e1Schristos return NULL; /* Multiple status, or unknown */
2784e98e3e1Schristos } /* decContextSetStatusFromString */
2794e98e3e1Schristos
2804e98e3e1Schristos /* ------------------------------------------------------------------ */
2814e98e3e1Schristos /* decContextSetStatusFromStringQuiet -- set status from a string */
2824e98e3e1Schristos /* */
2834e98e3e1Schristos /* context is the context structure to be updated */
2844e98e3e1Schristos /* string is a string exactly equal to one that might be returned */
2854e98e3e1Schristos /* by decContextStatusToString */
2864e98e3e1Schristos /* */
2874e98e3e1Schristos /* The status bit corresponding to the string is set; no trap is */
2884e98e3e1Schristos /* raised. */
2894e98e3e1Schristos /* */
2904e98e3e1Schristos /* returns the context structure, unless the string is equal to */
2914e98e3e1Schristos /* DEC_Condition_MU or is not recognized. In these cases NULL is */
2924e98e3e1Schristos /* returned. */
2934e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextSetStatusFromStringQuiet(decContext * context,const char * string)2944e98e3e1Schristos decContext * decContextSetStatusFromStringQuiet(decContext *context,
2954e98e3e1Schristos const char *string) {
2964e98e3e1Schristos if (strcmp(string, DEC_Condition_CS)==0)
2974e98e3e1Schristos return decContextSetStatusQuiet(context, DEC_Conversion_syntax);
2984e98e3e1Schristos if (strcmp(string, DEC_Condition_DZ)==0)
2994e98e3e1Schristos return decContextSetStatusQuiet(context, DEC_Division_by_zero);
3004e98e3e1Schristos if (strcmp(string, DEC_Condition_DI)==0)
3014e98e3e1Schristos return decContextSetStatusQuiet(context, DEC_Division_impossible);
3024e98e3e1Schristos if (strcmp(string, DEC_Condition_DU)==0)
3034e98e3e1Schristos return decContextSetStatusQuiet(context, DEC_Division_undefined);
3044e98e3e1Schristos if (strcmp(string, DEC_Condition_IE)==0)
3054e98e3e1Schristos return decContextSetStatusQuiet(context, DEC_Inexact);
3064e98e3e1Schristos if (strcmp(string, DEC_Condition_IS)==0)
3074e98e3e1Schristos return decContextSetStatusQuiet(context, DEC_Insufficient_storage);
3084e98e3e1Schristos if (strcmp(string, DEC_Condition_IC)==0)
3094e98e3e1Schristos return decContextSetStatusQuiet(context, DEC_Invalid_context);
3104e98e3e1Schristos if (strcmp(string, DEC_Condition_IO)==0)
3114e98e3e1Schristos return decContextSetStatusQuiet(context, DEC_Invalid_operation);
3124e98e3e1Schristos #if DECSUBSET
3134e98e3e1Schristos if (strcmp(string, DEC_Condition_LD)==0)
3144e98e3e1Schristos return decContextSetStatusQuiet(context, DEC_Lost_digits);
3154e98e3e1Schristos #endif
3164e98e3e1Schristos if (strcmp(string, DEC_Condition_OV)==0)
3174e98e3e1Schristos return decContextSetStatusQuiet(context, DEC_Overflow);
3184e98e3e1Schristos if (strcmp(string, DEC_Condition_PA)==0)
3194e98e3e1Schristos return decContextSetStatusQuiet(context, DEC_Clamped);
3204e98e3e1Schristos if (strcmp(string, DEC_Condition_RO)==0)
3214e98e3e1Schristos return decContextSetStatusQuiet(context, DEC_Rounded);
3224e98e3e1Schristos if (strcmp(string, DEC_Condition_SU)==0)
3234e98e3e1Schristos return decContextSetStatusQuiet(context, DEC_Subnormal);
3244e98e3e1Schristos if (strcmp(string, DEC_Condition_UN)==0)
3254e98e3e1Schristos return decContextSetStatusQuiet(context, DEC_Underflow);
3264e98e3e1Schristos if (strcmp(string, DEC_Condition_ZE)==0)
3274e98e3e1Schristos return context;
3284e98e3e1Schristos return NULL; /* Multiple status, or unknown */
3294e98e3e1Schristos } /* decContextSetStatusFromStringQuiet */
3304e98e3e1Schristos
3314e98e3e1Schristos /* ------------------------------------------------------------------ */
3324e98e3e1Schristos /* decContextSetStatusQuiet -- set status without trap */
3334e98e3e1Schristos /* */
3344e98e3e1Schristos /* context is the context structure to be updated */
3354e98e3e1Schristos /* status is the DEC_ exception code */
3364e98e3e1Schristos /* returns the context structure */
3374e98e3e1Schristos /* */
3384e98e3e1Schristos /* No error is possible. */
3394e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextSetStatusQuiet(decContext * context,uInt status)3404e98e3e1Schristos decContext * decContextSetStatusQuiet(decContext *context, uInt status) {
3414e98e3e1Schristos context->status|=status;
3424e98e3e1Schristos return context;} /* decContextSetStatusQuiet */
3434e98e3e1Schristos
3444e98e3e1Schristos /* ------------------------------------------------------------------ */
3454e98e3e1Schristos /* decContextStatusToString -- convert status flags to a string */
3464e98e3e1Schristos /* */
3474e98e3e1Schristos /* context is a context with valid status field */
3484e98e3e1Schristos /* */
3494e98e3e1Schristos /* returns a constant string describing the condition. If multiple */
3504e98e3e1Schristos /* (or no) flags are set, a generic constant message is returned. */
3514e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextStatusToString(const decContext * context)3524e98e3e1Schristos const char *decContextStatusToString(const decContext *context) {
3534e98e3e1Schristos Int status=context->status;
3544e98e3e1Schristos
3554e98e3e1Schristos /* test the five IEEE first, as some of the others are ambiguous when */
3564e98e3e1Schristos /* DECEXTFLAG=0 */
3574e98e3e1Schristos if (status==DEC_Invalid_operation ) return DEC_Condition_IO;
3584e98e3e1Schristos if (status==DEC_Division_by_zero ) return DEC_Condition_DZ;
3594e98e3e1Schristos if (status==DEC_Overflow ) return DEC_Condition_OV;
3604e98e3e1Schristos if (status==DEC_Underflow ) return DEC_Condition_UN;
3614e98e3e1Schristos if (status==DEC_Inexact ) return DEC_Condition_IE;
3624e98e3e1Schristos
3634e98e3e1Schristos if (status==DEC_Division_impossible ) return DEC_Condition_DI;
3644e98e3e1Schristos if (status==DEC_Division_undefined ) return DEC_Condition_DU;
3654e98e3e1Schristos if (status==DEC_Rounded ) return DEC_Condition_RO;
3664e98e3e1Schristos if (status==DEC_Clamped ) return DEC_Condition_PA;
3674e98e3e1Schristos if (status==DEC_Subnormal ) return DEC_Condition_SU;
3684e98e3e1Schristos if (status==DEC_Conversion_syntax ) return DEC_Condition_CS;
3694e98e3e1Schristos if (status==DEC_Insufficient_storage ) return DEC_Condition_IS;
3704e98e3e1Schristos if (status==DEC_Invalid_context ) return DEC_Condition_IC;
3714e98e3e1Schristos #if DECSUBSET
3724e98e3e1Schristos if (status==DEC_Lost_digits ) return DEC_Condition_LD;
3734e98e3e1Schristos #endif
3744e98e3e1Schristos if (status==0 ) return DEC_Condition_ZE;
3754e98e3e1Schristos return DEC_Condition_MU; /* Multiple errors */
3764e98e3e1Schristos } /* decContextStatusToString */
3774e98e3e1Schristos
3784e98e3e1Schristos /* ------------------------------------------------------------------ */
3794e98e3e1Schristos /* decContextTestEndian -- test whether DECLITEND is set correctly */
3804e98e3e1Schristos /* */
3814e98e3e1Schristos /* quiet is 1 to suppress message; 0 otherwise */
3824e98e3e1Schristos /* returns 0 if DECLITEND is correct */
3834e98e3e1Schristos /* 1 if DECLITEND is incorrect and should be 1 */
3844e98e3e1Schristos /* -1 if DECLITEND is incorrect and should be 0 */
3854e98e3e1Schristos /* */
3864e98e3e1Schristos /* A message is displayed if the return value is not 0 and quiet==0. */
3874e98e3e1Schristos /* */
3884e98e3e1Schristos /* No error is possible. */
3894e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextTestEndian(Flag quiet)3904e98e3e1Schristos Int decContextTestEndian(Flag quiet) {
3914e98e3e1Schristos Int res=0; /* optimist */
3924e98e3e1Schristos uInt dle=(uInt)DECLITEND; /* unsign */
3934e98e3e1Schristos if (dle>1) dle=1; /* ensure 0 or 1 */
3944e98e3e1Schristos
3954e98e3e1Schristos if (LITEND!=DECLITEND) {
3964e98e3e1Schristos if (!quiet) {
3974e98e3e1Schristos #if DECCHECK
3984e98e3e1Schristos const char *adj;
3994e98e3e1Schristos if (LITEND) adj="little";
4004e98e3e1Schristos else adj="big";
4014e98e3e1Schristos printf("Warning: DECLITEND is set to %d, but this computer appears to be %s-endian\n",
4024e98e3e1Schristos DECLITEND, adj);
4034e98e3e1Schristos #endif
4044e98e3e1Schristos }
4054e98e3e1Schristos res=(Int)LITEND-dle;
4064e98e3e1Schristos }
4074e98e3e1Schristos return res;
4084e98e3e1Schristos } /* decContextTestEndian */
4094e98e3e1Schristos
4104e98e3e1Schristos /* ------------------------------------------------------------------ */
4114e98e3e1Schristos /* decContextTestSavedStatus -- test bits in saved status */
4124e98e3e1Schristos /* */
4134e98e3e1Schristos /* oldstatus is the status word to be tested */
4144e98e3e1Schristos /* mask indicates the bits to be tested (the oldstatus bits that */
4154e98e3e1Schristos /* correspond to each 1 bit in the mask are tested) */
4164e98e3e1Schristos /* returns 1 if any of the tested bits are 1, or 0 otherwise */
4174e98e3e1Schristos /* */
4184e98e3e1Schristos /* No error is possible. */
4194e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextTestSavedStatus(uInt oldstatus,uInt mask)4204e98e3e1Schristos uInt decContextTestSavedStatus(uInt oldstatus, uInt mask) {
4214e98e3e1Schristos return (oldstatus&mask)!=0;
4224e98e3e1Schristos } /* decContextTestSavedStatus */
4234e98e3e1Schristos
4244e98e3e1Schristos /* ------------------------------------------------------------------ */
4254e98e3e1Schristos /* decContextTestStatus -- test bits in current status */
4264e98e3e1Schristos /* */
4274e98e3e1Schristos /* context is the context structure to be updated */
4284e98e3e1Schristos /* mask indicates the bits to be tested (the status bits that */
4294e98e3e1Schristos /* correspond to each 1 bit in the mask are tested) */
4304e98e3e1Schristos /* returns 1 if any of the tested bits are 1, or 0 otherwise */
4314e98e3e1Schristos /* */
4324e98e3e1Schristos /* No error is possible. */
4334e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextTestStatus(decContext * context,uInt mask)4344e98e3e1Schristos uInt decContextTestStatus(decContext *context, uInt mask) {
4354e98e3e1Schristos return (context->status&mask)!=0;
4364e98e3e1Schristos } /* decContextTestStatus */
4374e98e3e1Schristos
4384e98e3e1Schristos /* ------------------------------------------------------------------ */
4394e98e3e1Schristos /* decContextZeroStatus -- clear all status bits */
4404e98e3e1Schristos /* */
4414e98e3e1Schristos /* context is the context structure to be updated */
4424e98e3e1Schristos /* returns context */
4434e98e3e1Schristos /* */
4444e98e3e1Schristos /* No error is possible. */
4454e98e3e1Schristos /* ------------------------------------------------------------------ */
decContextZeroStatus(decContext * context)4464e98e3e1Schristos decContext *decContextZeroStatus(decContext *context) {
4474e98e3e1Schristos context->status=0;
4484e98e3e1Schristos return context;
4494e98e3e1Schristos } /* decContextZeroStatus */
4504e98e3e1Schristos
451