Ruby
1.9.3p429(2013-05-15revision40747)
Main Page
Modules
Data Structures
Files
File List
Globals
ext
bigdecimal
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
* You may distribute under the terms of either the GNU General Public
8
* License or the Artistic License, as specified in the README file
9
* of this BigDecimal distribution.
10
*
11
* NOTES:
12
* 2003-03-28 V1.0 checked in.
13
*
14
*/
15
16
#ifndef RUBY_BIG_DECIMAL_H
17
#define RUBY_BIG_DECIMAL_H 1
18
19
#include "
ruby/ruby.h
"
20
#include <float.h>
21
22
#if defined(__cplusplus)
23
extern
"C"
{
24
#endif
25
26
#ifndef HAVE_LABS
27
static
inline
long
28
labs
(
long
const
x)
29
{
30
if
(x < 0)
return
-x;
31
return
x;
32
}
33
#endif
34
35
#ifndef HAVE_LLABS
36
static
inline
LONG_LONG
37
llabs
(LONG_LONG
const
x)
38
{
39
if
(x < 0)
return
-x;
40
return
x;
41
}
42
#endif
43
44
#ifdef vabs
45
# undef vabs
46
#endif
47
#if SIZEOF_VALUE <= SIZEOF_INT
48
# define vabs abs
49
#elif SIZEOF_VALUE <= SIZEOF_LONG
50
# define vabs labs
51
#elif SIZEOF_VALUE <= SIZEOF_LONG_LONG
52
# define vabs llabs
53
#endif
54
55
extern
VALUE
rb_cBigDecimal
;
56
57
#if 0 || SIZEOF_BDIGITS >= 16
58
# define RMPD_COMPONENT_FIGURES 38
59
# define RMPD_BASE ((BDIGIT)100000000000000000000000000000000000000U)
60
#elif SIZEOF_BDIGITS >= 8
61
# define RMPD_COMPONENT_FIGURES 19
62
# define RMPD_BASE ((BDIGIT)10000000000000000000U)
63
#elif SIZEOF_BDIGITS >= 4
64
# define RMPD_COMPONENT_FIGURES 9
65
# define RMPD_BASE ((BDIGIT)1000000000U)
66
#elif SIZEOF_BDIGITS >= 2
67
# define RMPD_COMPONENT_FIGURES 4
68
# define RMPD_BASE ((BDIGIT)10000U)
69
#else
70
# define RMPD_COMPONENT_FIGURES 2
71
# define RMPD_BASE ((BDIGIT)100U)
72
#endif
73
74
75
/*
76
* NaN & Infinity
77
*/
78
#define SZ_NaN "NaN"
79
#define SZ_INF "Infinity"
80
#define SZ_PINF "+Infinity"
81
#define SZ_NINF "-Infinity"
82
83
/*
84
* #define VP_EXPORT other than static to let VP_ routines
85
* be called from outside of this module.
86
*/
87
#define VP_EXPORT static
88
89
/* Exception codes */
90
#define VP_EXCEPTION_ALL ((unsigned short)0x00FF)
91
#define VP_EXCEPTION_INFINITY ((unsigned short)0x0001)
92
#define VP_EXCEPTION_NaN ((unsigned short)0x0002)
93
#define VP_EXCEPTION_UNDERFLOW ((unsigned short)0x0004)
94
#define VP_EXCEPTION_OVERFLOW ((unsigned short)0x0001)
/* 0x0008) */
95
#define VP_EXCEPTION_ZERODIVIDE ((unsigned short)0x0010)
96
97
/* Following 2 exceptions cann't controlled by user */
98
#define VP_EXCEPTION_OP ((unsigned short)0x0020)
99
#define VP_EXCEPTION_MEMORY ((unsigned short)0x0040)
100
101
#define RMPD_EXCEPTION_MODE_DEFAULT 0U
102
103
/* Computation mode */
104
#define VP_ROUND_MODE ((unsigned short)0x0100)
105
#define VP_ROUND_UP 1
106
#define VP_ROUND_DOWN 2
107
#define VP_ROUND_HALF_UP 3
108
#define VP_ROUND_HALF_DOWN 4
109
#define VP_ROUND_CEIL 5
110
#define VP_ROUND_FLOOR 6
111
#define VP_ROUND_HALF_EVEN 7
112
113
#define RMPD_ROUNDING_MODE_DEFAULT VP_ROUND_HALF_UP
114
115
#define VP_SIGN_NaN 0
/* NaN */
116
#define VP_SIGN_POSITIVE_ZERO 1
/* Positive zero */
117
#define VP_SIGN_NEGATIVE_ZERO -1
/* Negative zero */
118
#define VP_SIGN_POSITIVE_FINITE 2
/* Positive finite number */
119
#define VP_SIGN_NEGATIVE_FINITE -2
/* Negative finite number */
120
#define VP_SIGN_POSITIVE_INFINITE 3
/* Positive infinite number */
121
#define VP_SIGN_NEGATIVE_INFINITE -3
/* Negative infinite number */
122
123
/*
124
* VP representation
125
* r = 0.xxxxxxxxx *BASE**exponent
126
*/
127
typedef
struct
{
128
VALUE
obj
;
/* Back pointer(VALUE) for Ruby object. */
129
size_t
MaxPrec
;
/* Maximum precision size */
130
/* This is the actual size of pfrac[] */
131
/*(frac[0] to frac[MaxPrec] are available). */
132
size_t
Prec
;
/* Current precision size. */
133
/* This indicates how much the. */
134
/* the array frac[] is actually used. */
135
SIGNED_VALUE
exponent
;
/* Exponent part. */
136
short
sign
;
/* Attributes of the value. */
137
/*
138
* ==0 : NaN
139
* 1 : Positive zero
140
* -1 : Negative zero
141
* 2 : Positive number
142
* -2 : Negative number
143
* 3 : Positive infinite number
144
* -3 : Negative infinite number
145
*/
146
short
flag
;
/* Not used in vp_routines,space for user. */
147
BDIGIT
frac[1];
/* Pointer to array of fraction part. */
148
}
Real
;
149
150
/*
151
* ------------------
152
* EXPORTables.
153
* ------------------
154
*/
155
156
VP_EXPORT
Real
*
157
VpNewRbClass
(
size_t
mx,
char
const
*str,
VALUE
klass);
158
159
VP_EXPORT
Real
*
VpCreateRbObject
(
size_t
mx,
const
char
*str);
160
161
static
inline
BDIGIT
162
rmpd_base_value
(
void
) {
return
RMPD_BASE
; }
163
static
inline
size_t
164
rmpd_component_figures
(
void
) {
return
RMPD_COMPONENT_FIGURES
; }
165
static
inline
size_t
166
rmpd_double_figures
(
void
) {
return
1+
DBL_DIG
; }
167
168
#define VpBaseFig() rmpd_component_figures()
169
#define VpDblFig() rmpd_double_figures()
170
#define VpBaseVal() rmpd_base_value()
171
172
/* Zero,Inf,NaN (isinf(),isnan() used to check) */
173
VP_EXPORT
double
VpGetDoubleNaN
(
void
);
174
VP_EXPORT
double
VpGetDoublePosInf
(
void
);
175
VP_EXPORT
double
VpGetDoubleNegInf
(
void
);
176
VP_EXPORT
double
VpGetDoubleNegZero
(
void
);
177
178
/* These 2 functions added at v1.1.7 */
179
VP_EXPORT
size_t
VpGetPrecLimit
(
void
);
180
VP_EXPORT
size_t
VpSetPrecLimit
(
size_t
n);
181
182
/* Round mode */
183
VP_EXPORT
int
VpIsRoundMode
(
unsigned
short
n);
184
VP_EXPORT
unsigned
short
VpGetRoundMode
(
void
);
185
VP_EXPORT
unsigned
short
VpSetRoundMode
(
unsigned
short
n);
186
187
VP_EXPORT
int
VpException
(
unsigned
short
f,
const
char
*str,
int
always);
188
#if 0
/* unused */
189
VP_EXPORT
int
VpIsNegDoubleZero(
double
v
);
190
#endif
191
VP_EXPORT
size_t
VpNumOfChars
(
Real
*vp,
const
char
*pszFmt);
192
VP_EXPORT
size_t
VpInit
(
BDIGIT
BaseVal);
193
VP_EXPORT
void
*
VpMemAlloc
(
size_t
mb);
194
VP_EXPORT
void
VpFree
(
Real
*pv);
195
VP_EXPORT
Real
*
VpAlloc
(
size_t
mx,
const
char
*szVal);
196
VP_EXPORT
size_t
VpAsgn
(
Real
*c,
Real
*a,
int
isw);
197
VP_EXPORT
size_t
VpAddSub
(
Real
*c,
Real
*a,
Real
*b,
int
operation);
198
VP_EXPORT
size_t
VpMult
(
Real
*c,
Real
*a,
Real
*b);
199
VP_EXPORT
size_t
VpDivd
(
Real
*c,
Real
*r,
Real
*a,
Real
*b);
200
VP_EXPORT
int
VpComp
(
Real
*a,
Real
*b);
201
VP_EXPORT
ssize_t
VpExponent10
(
Real
*a);
202
VP_EXPORT
void
VpSzMantissa
(
Real
*a,
char
*psz);
203
VP_EXPORT
int
VpToSpecialString
(
Real
*a,
char
*psz,
int
fPlus);
204
VP_EXPORT
void
VpToString
(
Real
*a,
char
*psz,
size_t
fFmt,
int
fPlus);
205
VP_EXPORT
void
VpToFString
(
Real
*a,
char
*psz,
size_t
fFmt,
int
fPlus);
206
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
);
207
VP_EXPORT
int
VpVtoD
(
double
*d,
SIGNED_VALUE
*e,
Real
*m);
208
VP_EXPORT
void
VpDtoV
(
Real
*m,
double
d);
209
#if 0
/* unused */
210
VP_EXPORT
void
VpItoV(
Real
*m,S_INT ival);
211
#endif
212
VP_EXPORT
int
VpSqrt
(
Real
*y,
Real
*x);
213
VP_EXPORT
int
VpActiveRound
(
Real
*y,
Real
*x,
unsigned
short
f, ssize_t il);
214
VP_EXPORT
int
VpMidRound
(
Real
*y,
unsigned
short
f, ssize_t nf);
215
VP_EXPORT
int
VpLeftRound
(
Real
*y,
unsigned
short
f, ssize_t nf);
216
VP_EXPORT
void
VpFrac
(
Real
*y,
Real
*x);
217
VP_EXPORT
int
VpPower
(
Real
*y,
Real
*x,
SIGNED_VALUE
n);
218
219
/* VP constants */
220
VP_EXPORT
Real
*
VpOne
(
void
);
221
222
/*
223
* ------------------
224
* MACRO definitions.
225
* ------------------
226
*/
227
#define Abs(a) (((a)>= 0)?(a):(-(a)))
228
#define Max(a, b) (((a)>(b))?(a):(b))
229
#define Min(a, b) (((a)>(b))?(b):(a))
230
231
#define VpMaxPrec(a) ((a)->MaxPrec)
232
#define VpPrec(a) ((a)->Prec)
233
#define VpGetFlag(a) ((a)->flag)
234
235
/* Sign */
236
237
/* VpGetSign(a) returns 1,-1 if a>0,a<0 respectively */
238
#define VpGetSign(a) (((a)->sign>0)?1:(-1))
239
/* Change sign of a to a>0,a<0 if s = 1,-1 respectively */
240
#define VpChangeSign(a,s) {if((s)>0) (a)->sign=(short)Abs((ssize_t)(a)->sign);else (a)->sign=-(short)Abs((ssize_t)(a)->sign);}
241
/* Sets sign of a to a>0,a<0 if s = 1,-1 respectively */
242
#define VpSetSign(a,s) {if((s)>0) (a)->sign=(short)VP_SIGN_POSITIVE_FINITE;else (a)->sign=(short)VP_SIGN_NEGATIVE_FINITE;}
243
244
/* 1 */
245
#define VpSetOne(a) {(a)->Prec=(a)->exponent=(a)->frac[0]=1;(a)->sign=VP_SIGN_POSITIVE_FINITE;}
246
247
/* ZEROs */
248
#define VpIsPosZero(a) ((a)->sign==VP_SIGN_POSITIVE_ZERO)
249
#define VpIsNegZero(a) ((a)->sign==VP_SIGN_NEGATIVE_ZERO)
250
#define VpIsZero(a) (VpIsPosZero(a) || VpIsNegZero(a))
251
#define VpSetPosZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_ZERO)
252
#define VpSetNegZero(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_ZERO)
253
#define VpSetZero(a,s) ( ((s)>0)?VpSetPosZero(a):VpSetNegZero(a) )
254
255
/* NaN */
256
#define VpIsNaN(a) ((a)->sign==VP_SIGN_NaN)
257
#define VpSetNaN(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NaN)
258
259
/* Infinity */
260
#define VpIsPosInf(a) ((a)->sign==VP_SIGN_POSITIVE_INFINITE)
261
#define VpIsNegInf(a) ((a)->sign==VP_SIGN_NEGATIVE_INFINITE)
262
#define VpIsInf(a) (VpIsPosInf(a) || VpIsNegInf(a))
263
#define VpIsDef(a) ( !(VpIsNaN(a)||VpIsInf(a)) )
264
#define VpSetPosInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_POSITIVE_INFINITE)
265
#define VpSetNegInf(a) ((a)->frac[0]=0,(a)->Prec=1,(a)->sign=VP_SIGN_NEGATIVE_INFINITE)
266
#define VpSetInf(a,s) ( ((s)>0)?VpSetPosInf(a):VpSetNegInf(a) )
267
#define VpHasVal(a) (a->frac[0])
268
#define VpIsOne(a) ((a->Prec==1)&&(a->frac[0]==1)&&(a->exponent==1))
269
#define VpExponent(a) (a->exponent)
270
#ifdef BIGDECIMAL_DEBUG
271
int
VpVarCheck(
Real
*
v
);
272
VP_EXPORT
int
VPrint(
FILE
*fp,
const
char
*cntl_chr,
Real
*a);
273
#endif
/* BIGDECIMAL_DEBUG */
274
275
#if defined(__cplusplus)
276
}
/* extern "C" { */
277
#endif
278
#endif
/* RUBY_BIG_DECIMAL_H */
279
Generated on Thu May 23 2013 20:33:00 for Ruby by
1.8.3