Ruby  3.1.0dev(2021-09-10revisionb76ad15ed0da636161de0243c547ee1e6fc95681)
bigdecimal.h
Go to the documentation of this file.
1 /*
2  *
3  * Ruby BigDecimal(Variable decimal precision) extension library.
4  *
5  * Copyright(C) 2002 by Shigeo Kobayashi(shigeo@tinyforest.gr.jp)
6  *
7  */
8 
9 #ifndef RUBY_BIG_DECIMAL_H
10 #define RUBY_BIG_DECIMAL_H 1
11 
12 #define RUBY_NO_OLD_COMPATIBILITY
13 #include "ruby/ruby.h"
14 #include "missing.h"
15 
16 #ifdef HAVE_FLOAT_H
17 # include <float.h>
18 #endif
19 
20 #ifdef HAVE_INT64_T
21 # define DECDIG uint32_t
22 # define DECDIG_DBL uint64_t
23 # define DECDIG_DBL_SIGNED int64_t
24 # define SIZEOF_DECDIG 4
25 # define PRI_DECDIG_PREFIX ""
26 # ifdef PRI_LL_PREFIX
27 # define PRI_DECDIG_DBL_PREFIX PRI_LL_PREFIX
28 # else
29 # define PRI_DECDIG_DBL_PREFIX "l"
30 # endif
31 #else
32 # define DECDIG uint16_t
33 # define DECDIG_DBL uint32_t
34 # define DECDIG_DBL_SIGNED int32_t
35 # define SIZEOF_DECDIG 2
36 # define PRI_DECDIG_PREFIX "h"
37 # define PRI_DECDIG_DBL_PREFIX ""
38 #endif
39 
40 #define PRIdDECDIG PRI_DECDIG_PREFIX"d"
41 #define PRIiDECDIG PRI_DECDIG_PREFIX"i"
42 #define PRIoDECDIG PRI_DECDIG_PREFIX"o"
43 #define PRIuDECDIG PRI_DECDIG_PREFIX"u"
44 #define PRIxDECDIG PRI_DECDIG_PREFIX"x"
45 #define PRIXDECDIG PRI_DECDIG_PREFIX"X"
46 
47 #define PRIdDECDIG_DBL PRI_DECDIG_DBL_PREFIX"d"
48 #define PRIiDECDIG_DBL PRI_DECDIG_DBL_PREFIX"i"
49 #define PRIoDECDIG_DBL PRI_DECDIG_DBL_PREFIX"o"
50 #define PRIuDECDIG_DBL PRI_DECDIG_DBL_PREFIX"u"
51 #define PRIxDECDIG_DBL PRI_DECDIG_DBL_PREFIX"x"
52 #define PRIXDECDIG_DBL PRI_DECDIG_DBL_PREFIX"X"
53 
54 #if SIZEOF_DECDIG == 4
55 # define BIGDECIMAL_BASE ((DECDIG)1000000000U)
56 # define BIGDECIMAL_COMPONENT_FIGURES 9
57 /*
58  * The number of components required for a 64-bit integer.
59  *
60  * INT64_MAX: 9_223372036_854775807
61  * UINT64_MAX: 18_446744073_709551615
62  */
63 # define BIGDECIMAL_INT64_MAX_LENGTH 3
64 
65 #elif SIZEOF_DECDIG == 2
66 # define BIGDECIMAL_BASE ((DECDIG)10000U)
67 # define BIGDECIMAL_COMPONENT_FIGURES 4
68 /*
69  * The number of components required for a 64-bit integer.
70  *
71  * INT64_MAX: 922_3372_0368_5477_5807
72  * UINT64_MAX: 1844_6744_0737_0955_1615
73  */
74 # define BIGDECIMAL_INT64_MAX_LENGTH 5
75 
76 #else
77 # error Unknown size of DECDIG
78 #endif
79 
80 #define BIGDECIMAL_DOUBLE_FIGURES (1+DBL_DIG)
81 
82 #if defined(__cplusplus)
83 extern "C" {
84 #if 0
85 } /* satisfy cc-mode */
86 #endif
87 #endif
88 
89 extern VALUE rb_cBigDecimal;
90 
91 /*
92  * NaN & Infinity
93  */
94 #define SZ_NaN "NaN"
95 #define SZ_INF "Infinity"
96 #define SZ_PINF "+Infinity"
97 #define SZ_NINF "-Infinity"
98 
99 /*
100  * #define VP_EXPORT other than static to let VP_ routines
101  * be called from outside of this module.
102  */
103 #define VP_EXPORT static
104 
105 /* Exception codes */
106 #define VP_EXCEPTION_ALL ((unsigned short)0x00FF)
107 #define VP_EXCEPTION_INFINITY ((unsigned short)0x0001)
108 #define VP_EXCEPTION_NaN ((unsigned short)0x0002)
109 #define VP_EXCEPTION_UNDERFLOW ((unsigned short)0x0004)
110 #define VP_EXCEPTION_OVERFLOW ((unsigned short)0x0001) /* 0x0008) */
111 #define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0010)
112 
113 /* Following 2 exceptions can't controlled by user */
114 #define VP_EXCEPTION_OP ((unsigned short)0x0020)
115 
116 #define BIGDECIMAL_EXCEPTION_MODE_DEFAULT 0U
117 
118 /* Computation mode */
119 #define VP_ROUND_MODE ((unsigned short)0x0100)
120 #define VP_ROUND_UP 1
121 #define VP_ROUND_DOWN 2
122 #define VP_ROUND_HALF_UP 3
123 #define VP_ROUND_HALF_DOWN 4
124 #define VP_ROUND_CEIL 5
125 #define VP_ROUND_FLOOR 6
126 #define VP_ROUND_HALF_EVEN 7
127 
128 #define BIGDECIMAL_ROUNDING_MODE_DEFAULT VP_ROUND_HALF_UP
129 
130 #define VP_SIGN_NaN 0 /* NaN */
131 #define VP_SIGN_POSITIVE_ZERO 1 /* Positive zero */
132 #define VP_SIGN_NEGATIVE_ZERO -1 /* Negative zero */
133 #define VP_SIGN_POSITIVE_FINITE 2 /* Positive finite number */
134 #define VP_SIGN_NEGATIVE_FINITE -2 /* Negative finite number */
135 #define VP_SIGN_POSITIVE_INFINITE 3 /* Positive infinite number */
136 #define VP_SIGN_NEGATIVE_INFINITE -3 /* Negative infinite number */
137 
138 #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
139 #define FLEXIBLE_ARRAY_SIZE /* */
140 #elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
141 #define FLEXIBLE_ARRAY_SIZE 0
142 #else
143 #define FLEXIBLE_ARRAY_SIZE 1
144 #endif
145 
146 /*
147  * VP representation
148  * r = 0.xxxxxxxxx *BASE**exponent
149  */
150 typedef struct {
151  VALUE obj; /* Back pointer(VALUE) for Ruby object. */
152  size_t MaxPrec; /* Maximum precision size */
153  /* This is the actual size of frac[] */
154  /*(frac[0] to frac[MaxPrec] are available). */
155  size_t Prec; /* Current precision size. */
156  /* This indicates how much the */
157  /* array frac[] is actually used. */
158  SIGNED_VALUE exponent; /* Exponent part. */
159  short sign; /* Attributes of the value. */
160  /*
161  * ==0 : NaN
162  * 1 : Positive zero
163  * -1 : Negative zero
164  * 2 : Positive number
165  * -2 : Negative number
166  * 3 : Positive infinite number
167  * -3 : Negative infinite number
168  */
169  short flag; /* Not used in vp_routines,space for user. */
170  DECDIG frac[FLEXIBLE_ARRAY_SIZE]; /* Array of fraction part. */
171 } Real;
172 
173 /*
174  * ------------------
175  * EXPORTables.
176  * ------------------
177  */
178 
179 VP_EXPORT Real *VpNewRbClass(size_t mx, char const *str, VALUE klass, bool strict_p, bool raise_exception);
180 
181 VP_EXPORT Real *VpCreateRbObject(size_t mx, const char *str, bool raise_exception);
182 
183 #define VpBaseFig() BIGDECIMAL_COMPONENT_FIGURES
184 #define VpDblFig() BIGDECIMAL_DOUBLE_FIGURES
185 #define VpBaseVal() BIGDECIMAL_BASE
186 
187 /* Zero,Inf,NaN (isinf(),isnan() used to check) */
188 VP_EXPORT double VpGetDoubleNaN(void);
189 VP_EXPORT double VpGetDoublePosInf(void);
190 VP_EXPORT double VpGetDoubleNegInf(void);
191 VP_EXPORT double VpGetDoubleNegZero(void);
192 
193 /* These 2 functions added at v1.1.7 */
194 VP_EXPORT size_t VpGetPrecLimit(void);
195 VP_EXPORT size_t VpSetPrecLimit(size_t n);
196 
197 /* Round mode */
198 VP_EXPORT int VpIsRoundMode(unsigned short n);
199 VP_EXPORT unsigned short VpGetRoundMode(void);
200 VP_EXPORT unsigned short VpSetRoundMode(unsigned short n);
201 
202 VP_EXPORT int VpException(unsigned short f,const char *str,int always);
203 #if 0 /* unused */
204 VP_EXPORT int VpIsNegDoubleZero(double v);
205 #endif
206 VP_EXPORT size_t VpNumOfChars(Real *vp,const char *pszFmt);
207 VP_EXPORT size_t VpInit(DECDIG BaseVal);
208 VP_EXPORT void *VpMemAlloc(size_t mb);
209 VP_EXPORT void *VpMemRealloc(void *ptr, size_t mb);
210 VP_EXPORT void VpFree(Real *pv);
211 VP_EXPORT Real *VpAlloc(size_t mx, const char *szVal, int strict_p, int exc);
212 VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw);
213 VP_EXPORT size_t VpAddSub(Real *c,Real *a,Real *b,int operation);
214 VP_EXPORT size_t VpMult(Real *c,Real *a,Real *b);
215 VP_EXPORT size_t VpDivd(Real *c,Real *r,Real *a,Real *b);
216 VP_EXPORT int VpComp(Real *a,Real *b);
217 VP_EXPORT ssize_t VpExponent10(Real *a);
218 VP_EXPORT void VpSzMantissa(Real *a,char *psz);
219 VP_EXPORT int VpToSpecialString(Real *a,char *psz,int fPlus);
220 VP_EXPORT void VpToString(Real *a, char *psz, size_t fFmt, int fPlus);
221 VP_EXPORT void VpToFString(Real *a, char *psz, size_t fFmt, int fPlus);
222 VP_EXPORT int VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne);
223 VP_EXPORT int VpVtoD(double *d, SIGNED_VALUE *e, Real *m);
224 VP_EXPORT void VpDtoV(Real *m,double d);
225 #if 0 /* unused */
226 VP_EXPORT void VpItoV(Real *m,S_INT ival);
227 #endif
228 VP_EXPORT int VpSqrt(Real *y,Real *x);
229 VP_EXPORT int VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t il);
230 VP_EXPORT int VpMidRound(Real *y, unsigned short f, ssize_t nf);
231 VP_EXPORT int VpLeftRound(Real *y, unsigned short f, ssize_t nf);
232 VP_EXPORT void VpFrac(Real *y, Real *x);
234 #define VpPower VpPowerByInt
235 
236 /* VP constants */
237 VP_EXPORT Real *VpOne(void);
238 
239 /*
240  * ------------------
241  * MACRO definitions.
242  * ------------------
243  */
244 #define Abs(a) (((a)>= 0)?(a):(-(a)))
245 #define Max(a, b) (((a)>(b))?(a):(b))
246 #define Min(a, b) (((a)>(b))?(b):(a))
247 
248 #define VpMaxPrec(a) ((a)->MaxPrec)
249 #define VpPrec(a) ((a)->Prec)
250 #define VpGetFlag(a) ((a)->flag)
251 
252 /* Sign */
253 
254 /* VpGetSign(a) returns 1,-1 if a>0,a<0 respectively */
255 #define VpGetSign(a) (((a)->sign>0)?1:(-1))
256 /* Change sign of a to a>0,a<0 if s = 1,-1 respectively */
257 #define VpChangeSign(a,s) {if((s)>0) (a)->sign=(short)Abs((ssize_t)(a)->sign);else (a)->sign=-(short)Abs((ssize_t)(a)->sign);}
258 /* Sets sign of a to a>0,a<0 if s = 1,-1 respectively */
259 #define VpSetSign(a,s) {if((s)>0) (a)->sign=(short)VP_SIGN_POSITIVE_FINITE;else (a)->sign=(short)VP_SIGN_NEGATIVE_FINITE;}
260 
261 /* 1 */
262 #define VpSetOne(a) {(a)->Prec=(a)->exponent=(a)->frac[0]=1;(a)->sign=VP_SIGN_POSITIVE_FINITE;}
263 
264 /* ZEROs */
265 #define VpIsPosZero(a) ((a)->sign==VP_SIGN_POSITIVE_ZERO)
266 #define VpIsNegZero(a) ((a)->sign==VP_SIGN_NEGATIVE_ZERO)
267 #define VpIsZero(a) (VpIsPosZero(a) || VpIsNegZero(a))
268 #define VpSetPosZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_ZERO)
269 #define VpSetNegZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_ZERO)
270 #define VpSetZero(a,s) (void)(((s)>0)?VpSetPosZero(a):VpSetNegZero(a))
271 
272 /* NaN */
273 #define VpIsNaN(a) ((a)->sign==VP_SIGN_NaN)
274 #define VpSetNaN(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NaN)
275 
276 /* Infinity */
277 #define VpIsPosInf(a) ((a)->sign==VP_SIGN_POSITIVE_INFINITE)
278 #define VpIsNegInf(a) ((a)->sign==VP_SIGN_NEGATIVE_INFINITE)
279 #define VpIsInf(a) (VpIsPosInf(a) || VpIsNegInf(a))
280 #define VpIsDef(a) ( !(VpIsNaN(a)||VpIsInf(a)) )
281 #define VpSetPosInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_INFINITE)
282 #define VpSetNegInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_INFINITE)
283 #define VpSetInf(a,s) (void)(((s)>0)?VpSetPosInf(a):VpSetNegInf(a))
284 #define VpHasVal(a) (a->frac[0])
285 #define VpIsOne(a) ((a->Prec==1)&&(a->frac[0]==1)&&(a->exponent==1))
286 #define VpExponent(a) (a->exponent)
287 #ifdef BIGDECIMAL_DEBUG
288 int VpVarCheck(Real * v);
289 #endif /* BIGDECIMAL_DEBUG */
290 
291 #if defined(__cplusplus)
292 #if 0
293 { /* satisfy cc-mode */
294 #endif
295 } /* extern "C" { */
296 #endif
297 #endif /* RUBY_BIG_DECIMAL_H */
VpGetPrecLimit
VP_EXPORT size_t VpGetPrecLimit(void)
Definition: bigdecimal.c:4140
VpAsgn
VP_EXPORT size_t VpAsgn(Real *c, Real *a, int isw)
Definition: bigdecimal.c:4817
SIGNED_VALUE
#define SIGNED_VALUE
Definition: value.h:40
VpMemRealloc
VP_EXPORT void * VpMemRealloc(void *ptr, size_t mb)
Definition: bigdecimal.c:4069
VpSzMantissa
VP_EXPORT void VpSzMantissa(Real *a, char *psz)
Definition: bigdecimal.c:5940
VpNumOfChars
VP_EXPORT size_t VpNumOfChars(Real *vp, const char *pszFmt)
Definition: bigdecimal.c:4411
VpException
VP_EXPORT int VpException(unsigned short f, const char *str, int always)
Definition: bigdecimal.c:4285
VpSetRoundMode
VP_EXPORT unsigned short VpSetRoundMode(unsigned short n)
Definition: bigdecimal.c:4209
VpDivd
VP_EXPORT size_t VpDivd(Real *c, Real *r, Real *a, Real *b)
Definition: bigdecimal.c:5445
ne
#define ne(x, y)
Definition: time.c:94
VpMemAlloc
VP_EXPORT void * VpMemAlloc(size_t mb)
Definition: bigdecimal.c:4058
VpToFString
VP_EXPORT void VpToFString(Real *a, char *psz, size_t fFmt, int fPlus)
Definition: bigdecimal.c:6070
y
size_t y
Definition: memory.h:207
VpVtoD
VP_EXPORT int VpVtoD(double *d, SIGNED_VALUE *e, Real *m)
Definition: bigdecimal.c:6296
VpCreateRbObject
VP_EXPORT Real * VpCreateRbObject(size_t mx, const char *str, bool raise_exception)
Definition: bigdecimal.c:736
ptr
struct RIMemo * ptr
Definition: debug.c:87
ruby.h
VpFree
VP_EXPORT void VpFree(Real *pv)
Definition: bigdecimal.c:4075
VpGetDoubleNegZero
VP_EXPORT double VpGetDoubleNegZero(void)
Definition: bigdecimal.c:4268
VP_EXPORT
#define VP_EXPORT
Definition: bigdecimal.h:103
VpSetPrecLimit
VP_EXPORT size_t VpSetPrecLimit(size_t n)
Definition: bigdecimal.c:4156
VpAlloc
VP_EXPORT Real * VpAlloc(size_t mx, const char *szVal, int strict_p, int exc)
Definition: bigdecimal.c:4586
VpIsRoundMode
VP_EXPORT int VpIsRoundMode(unsigned short n)
Definition: bigdecimal.c:4191
VpGetDoubleNegInf
VP_EXPORT double VpGetDoubleNegInf(void)
Definition: bigdecimal.c:4262
Real
Definition: bigdecimal.h:150
Real::MaxPrec
size_t MaxPrec
Definition: bigdecimal.h:152
Real::Prec
size_t Prec
Definition: bigdecimal.h:155
VpComp
VP_EXPORT int VpComp(Real *a, Real *b)
Definition: bigdecimal.c:5698
VpToSpecialString
VP_EXPORT int VpToSpecialString(Real *a, char *psz, int fPlus)
Definition: bigdecimal.c:5987
VpSqrt
VP_EXPORT int VpSqrt(Real *y, Real *x)
Definition: bigdecimal.c:6492
missing.h
rb_cBigDecimal
VALUE rb_cBigDecimal
Definition: bigdecimal.c:42
VpOne
VP_EXPORT Real * VpOne(void)
Definition: bigdecimal.c:4483
VpToString
VP_EXPORT void VpToString(Real *a, char *psz, size_t fFmt, int fPlus)
Definition: bigdecimal.c:6022
VpInit
VP_EXPORT size_t VpInit(DECDIG BaseVal)
Definition: bigdecimal.c:4455
VpDtoV
VP_EXPORT void VpDtoV(Real *m, double d)
Definition: bigdecimal.c:6360
VpAddSub
VP_EXPORT size_t VpAddSub(Real *c, Real *a, Real *b, int operation)
Definition: bigdecimal.c:4861
VALUE
unsigned long VALUE
Definition: value.h:38
VpExponent10
VP_EXPORT ssize_t VpExponent10(Real *a)
Definition: bigdecimal.c:5923
f
#define f
VpFrac
VP_EXPORT void VpFrac(Real *y, Real *x)
Definition: bigdecimal.c:6873
VpMidRound
VP_EXPORT int VpMidRound(Real *y, unsigned short f, ssize_t nf)
Definition: bigdecimal.c:6601
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
Real::sign
short sign
Definition: bigdecimal.h:159
VpLeftRound
VP_EXPORT int VpLeftRound(Real *y, unsigned short f, ssize_t nf)
Definition: bigdecimal.c:6763
VpPowerByInt
VP_EXPORT int VpPowerByInt(Real *y, Real *x, SIGNED_VALUE n)
Definition: bigdecimal.c:6921
VpGetDoubleNaN
VP_EXPORT double VpGetDoubleNaN(void)
Definition: bigdecimal.c:4250
VpActiveRound
VP_EXPORT int VpActiveRound(Real *y, Real *x, unsigned short f, ssize_t il)
Definition: bigdecimal.c:6778
DECDIG
#define DECDIG
Definition: bigdecimal.h:32
VpCtoV
VP_EXPORT int VpCtoV(Real *a, const char *int_chr, size_t ni, const char *frac, size_t nf, const char *exp_chr, size_t ne)
Definition: bigdecimal.c:6136
Real::obj
VALUE obj
Definition: bigdecimal.h:151
VpGetDoublePosInf
VP_EXPORT double VpGetDoublePosInf(void)
Definition: bigdecimal.c:4256
Real::exponent
SIGNED_VALUE exponent
Definition: bigdecimal.h:158
VpNewRbClass
VP_EXPORT Real * VpNewRbClass(size_t mx, char const *str, VALUE klass, bool strict_p, bool raise_exception)
Definition: bigdecimal.c:725
VpGetRoundMode
VP_EXPORT unsigned short VpGetRoundMode(void)
Definition: bigdecimal.c:4175
FLEXIBLE_ARRAY_SIZE
#define FLEXIBLE_ARRAY_SIZE
Definition: bigdecimal.h:139
VpMult
VP_EXPORT size_t VpMult(Real *c, Real *a, Real *b)
Definition: bigdecimal.c:5316
Real::flag
short flag
Definition: bigdecimal.h:169