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