|
Ruby 1.9.2p290(2011-07-09revision32553)
|
00001 /* 00002 * 00003 * Ruby BigDecimal(Variable decimal precision) extension library. 00004 * 00005 * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp) 00006 * 00007 * You may distribute under the terms of either the GNU General Public 00008 * License or the Artistic License, as specified in the README file 00009 * of this BigDecimal distribution. 00010 * 00011 * NOTES: 00012 * 2003-03-28 V1.0 checked in. 00013 * 00014 */ 00015 00016 #ifndef ____BIG_DECIMAL__H____ 00017 #define ____BIG_DECIMAL__H____ 00018 00019 #if defined(__cplusplus) 00020 extern "C" { 00021 #endif 00022 00023 /* 00024 * NaN & Infinity 00025 */ 00026 #define SZ_NaN "NaN" 00027 #define SZ_INF "Infinity" 00028 #define SZ_PINF "+Infinity" 00029 #define SZ_NINF "-Infinity" 00030 00031 /* 00032 * #define VP_EXPORT other than static to let VP_ routines 00033 * be called from outside of this module. 00034 */ 00035 #define VP_EXPORT static 00036 00037 #define U_LONG unsigned long 00038 #define S_LONG long 00039 #define U_INT unsigned int 00040 #define S_INT int 00041 00042 /* Exception codes */ 00043 #define VP_EXCEPTION_ALL ((unsigned short)0x00FF) 00044 #define VP_EXCEPTION_INFINITY ((unsigned short)0x0001) 00045 #define VP_EXCEPTION_NaN ((unsigned short)0x0002) 00046 #define VP_EXCEPTION_UNDERFLOW ((unsigned short)0x0004) 00047 #define VP_EXCEPTION_OVERFLOW ((unsigned short)0x0001) /* 0x0008) */ 00048 #define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0010) 00049 00050 /* Following 2 exceptions cann't controlled by user */ 00051 #define VP_EXCEPTION_OP ((unsigned short)0x0020) 00052 #define VP_EXCEPTION_MEMORY ((unsigned short)0x0040) 00053 00054 /* Computation mode */ 00055 #define VP_ROUND_MODE ((unsigned short)0x0100) 00056 #define VP_ROUND_UP 1 00057 #define VP_ROUND_DOWN 2 00058 #define VP_ROUND_HALF_UP 3 00059 #define VP_ROUND_HALF_DOWN 4 00060 #define VP_ROUND_CEIL 5 00061 #define VP_ROUND_FLOOR 6 00062 #define VP_ROUND_HALF_EVEN 7 00063 00064 #define VP_SIGN_NaN 0 /* NaN */ 00065 #define VP_SIGN_POSITIVE_ZERO 1 /* Positive zero */ 00066 #define VP_SIGN_NEGATIVE_ZERO -1 /* Negative zero */ 00067 #define VP_SIGN_POSITIVE_FINITE 2 /* Positive finite number */ 00068 #define VP_SIGN_NEGATIVE_FINITE -2 /* Negative finite number */ 00069 #define VP_SIGN_POSITIVE_INFINITE 3 /* Positive infinite number */ 00070 #define VP_SIGN_NEGATIVE_INFINITE -3 /* Negative infinite number */ 00071 00072 /* 00073 * VP representation 00074 * r = 0.xxxxxxxxx *BASE**exponent 00075 */ 00076 typedef struct { 00077 VALUE obj; /* Back pointer(VALUE) for Ruby object. */ 00078 U_LONG MaxPrec; /* Maximum precision size */ 00079 /* This is the actual size of pfrac[] */ 00080 /*(frac[0] to frac[MaxPrec] are available). */ 00081 U_LONG Prec; /* Current precision size. */ 00082 /* This indicates how much the. */ 00083 /* the array frac[] is actually used. */ 00084 S_INT exponent;/* Exponent part. */ 00085 short sign; /* Attributes of the value. */ 00086 /* 00087 * ==0 : NaN 00088 * 1 : Positive zero 00089 * -1 : Negative zero 00090 * 2 : Positive number 00091 * -2 : Negative number 00092 * 3 : Positive infinite number 00093 * -3 : Negative infinite number 00094 */ 00095 short flag; /* Not used in vp_routines,space for user. */ 00096 U_LONG frac[1]; /* Pointer to array of fraction part. */ 00097 } Real; 00098 00099 /* 00100 * ------------------ 00101 * EXPORTables. 00102 * ------------------ 00103 */ 00104 00105 VP_EXPORT Real * 00106 VpNewRbClass(U_LONG mx,char *str,VALUE klass); 00107 00108 VP_EXPORT Real *VpCreateRbObject(U_LONG mx,const char *str); 00109 00110 VP_EXPORT U_LONG VpBaseFig(void); 00111 VP_EXPORT U_LONG VpDblFig(void); 00112 VP_EXPORT U_LONG VpBaseVal(void); 00113 00114 /* Zero,Inf,NaN (isinf(),isnan() used to check) */ 00115 VP_EXPORT double VpGetDoubleNaN(void); 00116 VP_EXPORT double VpGetDoublePosInf(void); 00117 VP_EXPORT double VpGetDoubleNegInf(void); 00118 VP_EXPORT double VpGetDoubleNegZero(void); 00119 00120 /* These 2 functions added at v1.1.7 */ 00121 VP_EXPORT U_LONG VpGetPrecLimit(void); 00122 VP_EXPORT U_LONG VpSetPrecLimit(U_LONG n); 00123 00124 /* Round mode */ 00125 VP_EXPORT int VpIsRoundMode(unsigned long n); 00126 VP_EXPORT unsigned long VpGetRoundMode(void); 00127 VP_EXPORT unsigned long VpSetRoundMode(unsigned long n); 00128 00129 VP_EXPORT int VpException(unsigned short f,const char *str,int always); 00130 #if 0 /* unused */ 00131 VP_EXPORT int VpIsNegDoubleZero(double v); 00132 #endif 00133 VP_EXPORT U_LONG VpNumOfChars(Real *vp,const char *pszFmt); 00134 VP_EXPORT U_LONG VpInit(U_LONG BaseVal); 00135 VP_EXPORT void *VpMemAlloc(U_LONG mb); 00136 VP_EXPORT void VpFree(Real *pv); 00137 VP_EXPORT Real *VpAlloc(U_LONG mx, const char *szVal); 00138 VP_EXPORT U_LONG VpAsgn(Real *c,Real *a,int isw); 00139 VP_EXPORT U_LONG VpAddSub(Real *c,Real *a,Real *b,int operation); 00140 VP_EXPORT U_LONG VpMult(Real *c,Real *a,Real *b); 00141 VP_EXPORT U_LONG VpDivd(Real *c,Real *r,Real *a,Real *b); 00142 VP_EXPORT int VpComp(Real *a,Real *b); 00143 VP_EXPORT S_LONG VpExponent10(Real *a); 00144 VP_EXPORT void VpSzMantissa(Real *a,char *psz); 00145 VP_EXPORT int VpToSpecialString(Real *a,char *psz,int fPlus); 00146 VP_EXPORT void VpToString(Real *a,char *psz,int fFmt,int fPlus); 00147 VP_EXPORT void VpToFString(Real *a,char *psz,int fFmt,int fPlus); 00148 VP_EXPORT int VpCtoV(Real *a,const char *int_chr,U_LONG ni,const char *frac,U_LONG nf,const char *exp_chr,U_LONG ne); 00149 VP_EXPORT int VpVtoD(double *d,S_LONG *e,Real *m); 00150 VP_EXPORT void VpDtoV(Real *m,double d); 00151 #if 0 /* unused */ 00152 VP_EXPORT void VpItoV(Real *m,S_INT ival); 00153 #endif 00154 VP_EXPORT int VpSqrt(Real *y,Real *x); 00155 VP_EXPORT int VpActiveRound(Real *y,Real *x,int f,S_LONG il); 00156 VP_EXPORT int VpMidRound(Real *y, int f, S_LONG nf); 00157 VP_EXPORT int VpLeftRound(Real *y, int f, S_LONG nf); 00158 VP_EXPORT void VpFrac(Real *y,Real *x); 00159 VP_EXPORT int VpPower(Real *y,Real *x,S_INT n); 00160 00161 /* VP constants */ 00162 VP_EXPORT Real *VpOne(void); 00163 00164 /* 00165 * ------------------ 00166 * MACRO definitions. 00167 * ------------------ 00168 */ 00169 #define Abs(a) (((a)>= 0)?(a):(-(a))) 00170 #define Max(a, b) (((a)>(b))?(a):(b)) 00171 #define Min(a, b) (((a)>(b))?(b):(a)) 00172 00173 #define VpMaxPrec(a) ((a)->MaxPrec) 00174 #define VpPrec(a) ((a)->Prec) 00175 #define VpGetFlag(a) ((a)->flag) 00176 00177 /* Sign */ 00178 00179 /* VpGetSign(a) returns 1,-1 if a>0,a<0 respectively */ 00180 #define VpGetSign(a) (((a)->sign>0)?1:(-1)) 00181 /* Change sign of a to a>0,a<0 if s = 1,-1 respectively */ 00182 #define VpChangeSign(a,s) {if((s)>0) (a)->sign=(short)Abs((S_LONG)(a)->sign);else (a)->sign=-(short)Abs((S_LONG)(a)->sign);} 00183 /* Sets sign of a to a>0,a<0 if s = 1,-1 respectively */ 00184 #define VpSetSign(a,s) {if((s)>0) (a)->sign=(short)VP_SIGN_POSITIVE_FINITE;else (a)->sign=(short)VP_SIGN_NEGATIVE_FINITE;} 00185 00186 /* 1 */ 00187 #define VpSetOne(a) {(a)->frac[0]=(a)->Prec=(a)->exponent=1;(a)->sign=VP_SIGN_POSITIVE_FINITE;} 00188 00189 /* ZEROs */ 00190 #define VpIsPosZero(a) ((a)->sign==VP_SIGN_POSITIVE_ZERO) 00191 #define VpIsNegZero(a) ((a)->sign==VP_SIGN_NEGATIVE_ZERO) 00192 #define VpIsZero(a) (VpIsPosZero(a) || VpIsNegZero(a)) 00193 #define VpSetPosZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_ZERO) 00194 #define VpSetNegZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_ZERO) 00195 #define VpSetZero(a,s) ( ((s)>0)?VpSetPosZero(a):VpSetNegZero(a) ) 00196 00197 /* NaN */ 00198 #define VpIsNaN(a) ((a)->sign==VP_SIGN_NaN) 00199 #define VpSetNaN(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NaN) 00200 00201 /* Infinity */ 00202 #define VpIsPosInf(a) ((a)->sign==VP_SIGN_POSITIVE_INFINITE) 00203 #define VpIsNegInf(a) ((a)->sign==VP_SIGN_NEGATIVE_INFINITE) 00204 #define VpIsInf(a) (VpIsPosInf(a) || VpIsNegInf(a)) 00205 #define VpIsDef(a) ( !(VpIsNaN(a)||VpIsInf(a)) ) 00206 #define VpSetPosInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_INFINITE) 00207 #define VpSetNegInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_INFINITE) 00208 #define VpSetInf(a,s) ( ((s)>0)?VpSetPosInf(a):VpSetNegInf(a) ) 00209 #define VpHasVal(a) (a->frac[0]) 00210 #define VpIsOne(a) ((a->Prec==1)&&(a->frac[0]==1)&&(a->exponent==1)) 00211 #define VpExponent(a) (a->exponent) 00212 #ifdef BIGDECIMAL_DEBUG 00213 int VpVarCheck(Real * v); 00214 VP_EXPORT int VPrint(FILE *fp,const char *cntl_chr,Real *a); 00215 #endif /* BIGDECIMAL_DEBUG */ 00216 00217 #if defined(__cplusplus) 00218 } /* extern "C" { */ 00219 #endif 00220 #endif /* ____BIG_DECIMAL__H____ */ 00221
1.7.3