decimal 0.0.2 → 0.0.90.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +2 -2
- data/INSTALL +1 -2
- data/README +57 -1
- data/README.1st +1 -0
- data/TODO +25 -0
- data/decimal.c +927 -446
- data/decimal.gemspec +9 -5
- data/depend +1 -1
- data/extconf.rb +14 -0
- data/inum18.h +82 -8
- data/inum191.h +350 -0
- data/inum192.h +332 -0
- data/lib/decimal.rb +2 -0
- data/lib/decimal/math.rb +566 -0
- data/ruby18compat.h +55 -0
- data/test_decimal.rb +546 -0
- metadata +37 -11
data/decimal.gemspec
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "decimal"
|
3
3
|
s.rubyforge_project = s.name
|
4
|
-
s.version = "0.0.
|
5
|
-
s.date = "
|
4
|
+
s.version = "0.0.90.pre"
|
5
|
+
s.date = "2010-08-11"
|
6
6
|
s.summary = "(yet another) multi-precision decimal arithmetic library"
|
7
7
|
s.homepage = "http://decimal.rubyforge.org/"
|
8
8
|
s.description = <<-EOS.split("\n").map{|l|l.lstrip}.join(" ")
|
@@ -10,8 +10,12 @@ Gem::Specification.new do |s|
|
|
10
10
|
provides simple, compact, fast, precise, stable and easy-to-use solution.
|
11
11
|
EOS
|
12
12
|
s.extensions = "extconf.rb"
|
13
|
-
s.files = %w(COPYING GPL INSTALL README decimal.c decimal.gemspec
|
14
|
-
|
13
|
+
s.files = %w(COPYING GPL INSTALL README.1st README TODO decimal.c decimal.gemspec
|
14
|
+
depend extconf.rb inum18.h inum191.h inum192.h lib/decimal.rb
|
15
|
+
lib/decimal/math.rb ruby18compat.h test_decimal.rb)
|
16
|
+
s.extra_rdoc_files = %w(README)
|
17
|
+
s.has_rdoc = true
|
15
18
|
s.authors = "Tadashi Saito"
|
16
|
-
s.email = "
|
19
|
+
s.email = "tad.a.digger@gmail.com"
|
20
|
+
s.post_install_message = "\n\t\t" << IO.read("README.1st") << "\n"
|
17
21
|
end
|
data/depend
CHANGED
data/extconf.rb
CHANGED
@@ -1,3 +1,17 @@
|
|
1
1
|
require "mkmf"
|
2
|
+
|
2
3
|
(cflags = arg_config("--cflags")) && $CFLAGS << " #{cflags}"
|
4
|
+
version = if have_macro("RUBY_VERSION", "version.h")
|
5
|
+
"18"
|
6
|
+
elsif try_compile("int rb_str_hash(VALUE);")
|
7
|
+
"191"
|
8
|
+
else
|
9
|
+
"192"
|
10
|
+
end
|
11
|
+
$CFLAGS << " -DINUM_SOURCE_FILE=" + %(\\"inum#{version}.h\\")
|
12
|
+
have_func "rb_big_div"
|
13
|
+
have_func "rb_big_modulo"
|
14
|
+
have_func "rb_bigzero_p"
|
15
|
+
have_func "rb_usascii_str_new"
|
16
|
+
|
3
17
|
create_makefile "decimal"
|
data/inum18.h
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
/*
|
2
|
-
* Ruby's Integer part from ruby_1_8,
|
2
|
+
* Ruby's Integer part from ruby_1_8, r28324.
|
3
3
|
*
|
4
|
-
* These are hand copies (with
|
4
|
+
* These are hand copies (with few modifications) taken from original
|
5
5
|
* Ruby's code in "numeric.c" and "bignum.c," so the copyrights are
|
6
6
|
* held by matz and other contributors:
|
7
7
|
*
|
8
|
-
* Copyright (C) 1993-
|
8
|
+
* Copyright (C) 1993-2010 Yukihiro Matsumoto
|
9
9
|
*
|
10
10
|
*/
|
11
11
|
|
@@ -15,6 +15,28 @@
|
|
15
15
|
|
16
16
|
#define BDIGITS(x) ((BDIGIT*)RBIGNUM(x)->digits)
|
17
17
|
|
18
|
+
#ifndef HAVE_RB_BIGZERO_P
|
19
|
+
#define BIGZEROP(x) (RBIGNUM(x)->len == 0 || \
|
20
|
+
(BDIGITS(x)[0] == 0 && \
|
21
|
+
(RBIGNUM(x)->len == 1 || bigzero_p(x))))
|
22
|
+
|
23
|
+
static int
|
24
|
+
bigzero_p(VALUE x)
|
25
|
+
{
|
26
|
+
long i;
|
27
|
+
for (i = 0; i < RBIGNUM(x)->len; ++i) {
|
28
|
+
if (BDIGITS(x)[i]) return 0;
|
29
|
+
}
|
30
|
+
return 1;
|
31
|
+
}
|
32
|
+
|
33
|
+
static int
|
34
|
+
rb_bigzero_p(VALUE x)
|
35
|
+
{
|
36
|
+
return BIGZEROP(x);
|
37
|
+
}
|
38
|
+
#endif /* !HAVE_RB_BIGZERO_P */
|
39
|
+
|
18
40
|
static VALUE
|
19
41
|
rb_big_cmp(VALUE x, VALUE y)
|
20
42
|
{
|
@@ -65,7 +87,7 @@ rb_big_eq(VALUE x, VALUE y)
|
|
65
87
|
}
|
66
88
|
|
67
89
|
static VALUE
|
68
|
-
|
90
|
+
rb_big_uminus(VALUE x)
|
69
91
|
{
|
70
92
|
VALUE z = rb_big_clone(x);
|
71
93
|
|
@@ -87,10 +109,49 @@ rb_big_hash(VALUE x)
|
|
87
109
|
return LONG2FIX(key);
|
88
110
|
}
|
89
111
|
|
112
|
+
/* specially, copied from ruby_1_9_1 */
|
113
|
+
static VALUE
|
114
|
+
rb_big_odd_p(VALUE num)
|
115
|
+
{
|
116
|
+
if (BDIGITS(num)[0] & 1) {
|
117
|
+
return Qtrue;
|
118
|
+
}
|
119
|
+
return Qfalse;
|
120
|
+
}
|
121
|
+
|
90
122
|
/*
|
91
123
|
* copied from numeric.c
|
92
124
|
*/
|
93
125
|
|
126
|
+
static VALUE
|
127
|
+
flo_to_s(VALUE flt)
|
128
|
+
{
|
129
|
+
char buf[32];
|
130
|
+
double value = RFLOAT(flt)->value;
|
131
|
+
char *p, *e;
|
132
|
+
|
133
|
+
if (isinf(value))
|
134
|
+
return rb_str_new2(value < 0 ? "-Infinity" : "Infinity");
|
135
|
+
else if(isnan(value))
|
136
|
+
return rb_str_new2("NaN");
|
137
|
+
|
138
|
+
sprintf(buf, "%#.15g", value); /* ensure to print decimal point */
|
139
|
+
if (!(e = strchr(buf, 'e'))) {
|
140
|
+
e = buf + strlen(buf);
|
141
|
+
}
|
142
|
+
if (!ISDIGIT(e[-1])) { /* reformat if ended with decimal point (ex 111111111111111.) */
|
143
|
+
sprintf(buf, "%#.14e", value);
|
144
|
+
if (!(e = strchr(buf, 'e'))) {
|
145
|
+
e = buf + strlen(buf);
|
146
|
+
}
|
147
|
+
}
|
148
|
+
p = e;
|
149
|
+
while (p[-1]=='0' && ISDIGIT(p[-2]))
|
150
|
+
p--;
|
151
|
+
memmove(p, e, strlen(e)+1);
|
152
|
+
return rb_str_new2(buf);
|
153
|
+
}
|
154
|
+
|
94
155
|
static VALUE
|
95
156
|
fix_plus(VALUE x, VALUE y)
|
96
157
|
{
|
@@ -129,6 +190,10 @@ static VALUE
|
|
129
190
|
fix_mul(VALUE x, VALUE y)
|
130
191
|
{
|
131
192
|
if (FIXNUM_P(y)) {
|
193
|
+
#ifdef __HP_cc
|
194
|
+
/* avoids an optimization bug of HP aC++/ANSI C B3910B A.06.05 [Jul 25 2005] */
|
195
|
+
volatile
|
196
|
+
#endif
|
132
197
|
long a, b, c;
|
133
198
|
VALUE r;
|
134
199
|
|
@@ -184,7 +249,7 @@ fix_div(VALUE x, VALUE y)
|
|
184
249
|
return LONG2NUM(div);
|
185
250
|
}
|
186
251
|
/* modified */
|
187
|
-
return
|
252
|
+
return rb_big_div(rb_int2big(FIX2LONG(x)), y);
|
188
253
|
}
|
189
254
|
|
190
255
|
static VALUE
|
@@ -229,7 +294,7 @@ int_pow(long x, unsigned long y)
|
|
229
294
|
long xz = x * z;
|
230
295
|
if (!POSFIXABLE(xz) || xz / x != z) {
|
231
296
|
goto bignum;
|
232
|
-
|
297
|
+
}
|
233
298
|
z = xz;
|
234
299
|
}
|
235
300
|
} while (--y);
|
@@ -249,7 +314,7 @@ fix_pow(VALUE x, VALUE y)
|
|
249
314
|
if (b == 1) return x;
|
250
315
|
if (a == 0) {
|
251
316
|
if (b > 0) return INT2FIX(0);
|
252
|
-
|
317
|
+
/* modified */
|
253
318
|
rb_bug("fix_pow(): infinity returned");
|
254
319
|
return Qnil;
|
255
320
|
}
|
@@ -271,7 +336,7 @@ fix_pow(VALUE x, VALUE y)
|
|
271
336
|
if (a == 0) return INT2FIX(0);
|
272
337
|
if (a == 1) return INT2FIX(1);
|
273
338
|
if (a == -1) {
|
274
|
-
if ((
|
339
|
+
if (!rb_big_odd_p(y)) return INT2FIX(1); /* modified */
|
275
340
|
else return INT2FIX(-1);
|
276
341
|
}
|
277
342
|
x = rb_int2big(FIX2LONG(x));
|
@@ -300,3 +365,12 @@ fix_cmp(VALUE x, VALUE y)
|
|
300
365
|
return rb_big_cmp(rb_int2big(FIX2LONG(x)), y); /* modified */
|
301
366
|
}
|
302
367
|
}
|
368
|
+
|
369
|
+
static VALUE
|
370
|
+
fix_odd_p(VALUE num)
|
371
|
+
{
|
372
|
+
if (num & 2) {
|
373
|
+
return Qtrue;
|
374
|
+
}
|
375
|
+
return Qfalse;
|
376
|
+
}
|
data/inum191.h
ADDED
@@ -0,0 +1,350 @@
|
|
1
|
+
/*
|
2
|
+
* Ruby's Integer part from ruby_1_9_1, r27979.
|
3
|
+
*
|
4
|
+
* These are hand copies (with few modifications) taken from original
|
5
|
+
* Ruby's code in "numeric.c" and "bignum.c," so the copyrights are
|
6
|
+
* held by matz and other contributors:
|
7
|
+
*
|
8
|
+
* Copyright (C) 1993-2010 Yukihiro Matsumoto
|
9
|
+
*
|
10
|
+
*/
|
11
|
+
|
12
|
+
/*
|
13
|
+
* copied from bignum.c
|
14
|
+
*/
|
15
|
+
|
16
|
+
#define BDIGITS(x) (RBIGNUM_DIGITS(x))
|
17
|
+
|
18
|
+
#ifndef HAVE_RB_BIGZERO_P
|
19
|
+
#define BIGZEROP(x) (RBIGNUM_LEN(x) == 0 || \
|
20
|
+
(BDIGITS(x)[0] == 0 && \
|
21
|
+
(RBIGNUM_LEN(x) == 1 || bigzero_p(x))))
|
22
|
+
|
23
|
+
static int
|
24
|
+
bigzero_p(VALUE x)
|
25
|
+
{
|
26
|
+
long i;
|
27
|
+
for (i = RBIGNUM_LEN(x) - 1; 0 <= i; i--) {
|
28
|
+
if (BDIGITS(x)[i]) return 0;
|
29
|
+
}
|
30
|
+
return 1;
|
31
|
+
}
|
32
|
+
|
33
|
+
static int
|
34
|
+
rb_bigzero_p(VALUE x)
|
35
|
+
{
|
36
|
+
return BIGZEROP(x);
|
37
|
+
}
|
38
|
+
#endif /* !HAVE_RB_BIGZERO_P */
|
39
|
+
|
40
|
+
static VALUE
|
41
|
+
rb_big_uminus(VALUE x)
|
42
|
+
{
|
43
|
+
VALUE z = rb_big_clone(x);
|
44
|
+
|
45
|
+
RBIGNUM_SET_SIGN(z, !RBIGNUM_SIGN(x));
|
46
|
+
|
47
|
+
return rb_big_norm(z); /* modified to use exported one */
|
48
|
+
}
|
49
|
+
|
50
|
+
static VALUE
|
51
|
+
rb_big_hash(VALUE x)
|
52
|
+
{
|
53
|
+
int hash;
|
54
|
+
|
55
|
+
hash = rb_memhash(BDIGITS(x), sizeof(BDIGIT)*RBIGNUM_LEN(x)) ^ RBIGNUM_SIGN(x);
|
56
|
+
return INT2FIX(hash);
|
57
|
+
}
|
58
|
+
|
59
|
+
static VALUE
|
60
|
+
rb_big_odd_p(VALUE num)
|
61
|
+
{
|
62
|
+
if (BDIGITS(num)[0] & 1) {
|
63
|
+
return Qtrue;
|
64
|
+
}
|
65
|
+
return Qfalse;
|
66
|
+
}
|
67
|
+
|
68
|
+
/*
|
69
|
+
* copied from numeric.c
|
70
|
+
*/
|
71
|
+
|
72
|
+
static VALUE
|
73
|
+
flo_to_s(VALUE flt)
|
74
|
+
{
|
75
|
+
char buf[32];
|
76
|
+
double value = RFLOAT_VALUE(flt);
|
77
|
+
char *p, *e;
|
78
|
+
|
79
|
+
if (isinf(value))
|
80
|
+
return rb_usascii_str_new2(value < 0 ? "-Infinity" : "Infinity");
|
81
|
+
else if(isnan(value))
|
82
|
+
return rb_usascii_str_new2("NaN");
|
83
|
+
|
84
|
+
snprintf(buf, sizeof(buf), "%#.15g", value); /* ensure to print decimal point */
|
85
|
+
if (!(e = strchr(buf, 'e'))) {
|
86
|
+
e = buf + strlen(buf);
|
87
|
+
}
|
88
|
+
if (!ISDIGIT(e[-1])) { /* reformat if ended with decimal point (ex 111111111111111.) */
|
89
|
+
snprintf(buf, sizeof(buf), "%#.14e", value);
|
90
|
+
if (!(e = strchr(buf, 'e'))) {
|
91
|
+
e = buf + strlen(buf);
|
92
|
+
}
|
93
|
+
}
|
94
|
+
p = e;
|
95
|
+
while (p[-1]=='0' && ISDIGIT(p[-2]))
|
96
|
+
p--;
|
97
|
+
memmove(p, e, strlen(e)+1);
|
98
|
+
return rb_usascii_str_new2(buf);
|
99
|
+
}
|
100
|
+
|
101
|
+
static VALUE
|
102
|
+
fix_plus(VALUE x, VALUE y)
|
103
|
+
{
|
104
|
+
if (FIXNUM_P(y)) {
|
105
|
+
long a, b, c;
|
106
|
+
VALUE r;
|
107
|
+
|
108
|
+
a = FIX2LONG(x);
|
109
|
+
b = FIX2LONG(y);
|
110
|
+
c = a + b;
|
111
|
+
r = LONG2NUM(c);
|
112
|
+
|
113
|
+
return r;
|
114
|
+
}
|
115
|
+
return rb_big_plus(y, x); /* modified */
|
116
|
+
}
|
117
|
+
|
118
|
+
static VALUE
|
119
|
+
fix_minus(VALUE x, VALUE y)
|
120
|
+
{
|
121
|
+
if (FIXNUM_P(y)) {
|
122
|
+
long a, b, c;
|
123
|
+
VALUE r;
|
124
|
+
|
125
|
+
a = FIX2LONG(x);
|
126
|
+
b = FIX2LONG(y);
|
127
|
+
c = a - b;
|
128
|
+
r = LONG2NUM(c);
|
129
|
+
|
130
|
+
return r;
|
131
|
+
}
|
132
|
+
/* modified */
|
133
|
+
x = rb_int2big(FIX2LONG(x));
|
134
|
+
return rb_big_minus(x, y);
|
135
|
+
}
|
136
|
+
|
137
|
+
#define SQRT_LONG_MAX ((SIGNED_VALUE)1<<((SIZEOF_LONG*CHAR_BIT-1)/2))
|
138
|
+
/*tests if N*N would overflow*/
|
139
|
+
#define FIT_SQRT_LONG(n) (((n)<SQRT_LONG_MAX)&&((n)>=-SQRT_LONG_MAX))
|
140
|
+
|
141
|
+
static VALUE
|
142
|
+
fix_mul(VALUE x, VALUE y)
|
143
|
+
{
|
144
|
+
if (FIXNUM_P(y)) {
|
145
|
+
#ifdef __HP_cc
|
146
|
+
/* avoids an optimization bug of HP aC++/ANSI C B3910B A.06.05 [Jul 25 2005] */
|
147
|
+
volatile
|
148
|
+
#endif
|
149
|
+
long a, b;
|
150
|
+
#if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
|
151
|
+
LONG_LONG d;
|
152
|
+
#else
|
153
|
+
long c;
|
154
|
+
VALUE r;
|
155
|
+
#endif
|
156
|
+
|
157
|
+
a = FIX2LONG(x);
|
158
|
+
b = FIX2LONG(y);
|
159
|
+
|
160
|
+
#if SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
|
161
|
+
d = (LONG_LONG)a * b;
|
162
|
+
if (FIXABLE(d)) return LONG2FIX(d);
|
163
|
+
return rb_ll2inum(d);
|
164
|
+
#else
|
165
|
+
if (FIT_SQRT_LONG(a) && FIT_SQRT_LONG(b))
|
166
|
+
return LONG2FIX(a*b);
|
167
|
+
c = a * b;
|
168
|
+
r = LONG2FIX(c);
|
169
|
+
|
170
|
+
if (a == 0) return x;
|
171
|
+
if (FIX2LONG(r) != c || c/a != b) {
|
172
|
+
r = rb_big_mul(rb_int2big(a), rb_int2big(b));
|
173
|
+
}
|
174
|
+
return r;
|
175
|
+
#endif
|
176
|
+
}
|
177
|
+
/* modified */
|
178
|
+
return rb_big_mul(y, x);
|
179
|
+
}
|
180
|
+
|
181
|
+
static void
|
182
|
+
fixdivmod(long x, long y, long *divp, long *modp)
|
183
|
+
{
|
184
|
+
long div, mod;
|
185
|
+
|
186
|
+
if (y == 0) rb_bug("fixdivmod(): not reached"); /* modified */
|
187
|
+
if (y < 0) {
|
188
|
+
if (x < 0)
|
189
|
+
div = -x / -y;
|
190
|
+
else
|
191
|
+
div = - (x / -y);
|
192
|
+
}
|
193
|
+
else {
|
194
|
+
if (x < 0)
|
195
|
+
div = - (-x / y);
|
196
|
+
else
|
197
|
+
div = x / y;
|
198
|
+
}
|
199
|
+
mod = x - div*y;
|
200
|
+
if ((mod < 0 && y > 0) || (mod > 0 && y < 0)) {
|
201
|
+
mod += y;
|
202
|
+
div -= 1;
|
203
|
+
}
|
204
|
+
if (divp) *divp = div;
|
205
|
+
if (modp) *modp = mod;
|
206
|
+
}
|
207
|
+
|
208
|
+
/* extracted from fix_divide() */
|
209
|
+
static VALUE
|
210
|
+
fix_div(VALUE x, VALUE y)
|
211
|
+
{
|
212
|
+
if (FIXNUM_P(y)) {
|
213
|
+
long div;
|
214
|
+
|
215
|
+
fixdivmod(FIX2LONG(x), FIX2LONG(y), &div, 0);
|
216
|
+
return LONG2NUM(div);
|
217
|
+
}
|
218
|
+
/* modified */
|
219
|
+
x = rb_int2big(FIX2LONG(x));
|
220
|
+
return rb_big_div(x, y);
|
221
|
+
}
|
222
|
+
|
223
|
+
static VALUE
|
224
|
+
fix_divmod(VALUE x, VALUE y)
|
225
|
+
{
|
226
|
+
if (FIXNUM_P(y)) {
|
227
|
+
long div, mod;
|
228
|
+
|
229
|
+
fixdivmod(FIX2LONG(x), FIX2LONG(y), &div, &mod);
|
230
|
+
|
231
|
+
return rb_assoc_new(LONG2NUM(div), LONG2NUM(mod));
|
232
|
+
}
|
233
|
+
/* modified */
|
234
|
+
x = rb_int2big(FIX2LONG(x));
|
235
|
+
return rb_big_divmod(x, y);
|
236
|
+
}
|
237
|
+
|
238
|
+
static VALUE
|
239
|
+
int_pow(long x, unsigned long y)
|
240
|
+
{
|
241
|
+
int neg = x < 0;
|
242
|
+
long z = 1;
|
243
|
+
|
244
|
+
if (neg) x = -x;
|
245
|
+
if (y & 1)
|
246
|
+
z = x;
|
247
|
+
else
|
248
|
+
neg = 0;
|
249
|
+
y &= ~1;
|
250
|
+
do {
|
251
|
+
while (y % 2 == 0) {
|
252
|
+
if (!FIT_SQRT_LONG(x)) {
|
253
|
+
VALUE v;
|
254
|
+
bignum:
|
255
|
+
v = rb_big_pow(rb_int2big(x), LONG2NUM(y));
|
256
|
+
if (z != 1) v = rb_big_mul(rb_int2big(neg ? -z : z), v);
|
257
|
+
return v;
|
258
|
+
}
|
259
|
+
x = x * x;
|
260
|
+
y >>= 1;
|
261
|
+
}
|
262
|
+
{
|
263
|
+
long xz = x * z;
|
264
|
+
if (!POSFIXABLE(xz) || xz / x != z) {
|
265
|
+
goto bignum;
|
266
|
+
}
|
267
|
+
z = xz;
|
268
|
+
}
|
269
|
+
} while (--y);
|
270
|
+
if (neg) z = -z;
|
271
|
+
return LONG2NUM(z);
|
272
|
+
}
|
273
|
+
|
274
|
+
static VALUE fix_odd_p(VALUE num);
|
275
|
+
|
276
|
+
static VALUE
|
277
|
+
fix_pow(VALUE x, VALUE y)
|
278
|
+
{
|
279
|
+
/* static const double zero = 0.0; */
|
280
|
+
long a = FIX2LONG(x);
|
281
|
+
|
282
|
+
if (FIXNUM_P(y)) {
|
283
|
+
long b = FIX2LONG(y);
|
284
|
+
|
285
|
+
if (b < 0)
|
286
|
+
return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
|
287
|
+
|
288
|
+
if (b == 0) return INT2FIX(1);
|
289
|
+
if (b == 1) return x;
|
290
|
+
if (a == 0) {
|
291
|
+
if (b > 0) return INT2FIX(0);
|
292
|
+
/* modified */
|
293
|
+
rb_bug("fix_pow(): infinity returned");
|
294
|
+
return Qnil;
|
295
|
+
}
|
296
|
+
if (a == 1) return INT2FIX(1);
|
297
|
+
if (a == -1) {
|
298
|
+
if (b % 2 == 0)
|
299
|
+
return INT2FIX(1);
|
300
|
+
else
|
301
|
+
return INT2FIX(-1);
|
302
|
+
}
|
303
|
+
return int_pow(a, b);
|
304
|
+
}
|
305
|
+
/* modified */
|
306
|
+
if (rb_funcall(y, '<', 1, INT2FIX(0)))
|
307
|
+
return rb_funcall(rb_rational_raw1(x), rb_intern("**"), 1, y);
|
308
|
+
|
309
|
+
if (a == 0) return INT2FIX(0);
|
310
|
+
if (a == 1) return INT2FIX(1);
|
311
|
+
if (a == -1) {
|
312
|
+
/* modified */
|
313
|
+
#define int_even_p(x) \
|
314
|
+
(FIXNUM_P(x) ? !fix_odd_p(x) : !rb_big_odd_p(x))
|
315
|
+
if (int_even_p(y)) return INT2FIX(1);
|
316
|
+
#undef int_even_p
|
317
|
+
else return INT2FIX(-1);
|
318
|
+
}
|
319
|
+
x = rb_int2big(FIX2LONG(x));
|
320
|
+
return rb_big_pow(x, y);
|
321
|
+
}
|
322
|
+
|
323
|
+
static VALUE
|
324
|
+
fix_equal(VALUE x, VALUE y)
|
325
|
+
{
|
326
|
+
if (x == y) return Qtrue;
|
327
|
+
if (FIXNUM_P(y)) return Qfalse;
|
328
|
+
return rb_big_eq(y, x); /* modified */
|
329
|
+
}
|
330
|
+
|
331
|
+
static VALUE
|
332
|
+
fix_cmp(VALUE x, VALUE y)
|
333
|
+
{
|
334
|
+
if (x == y) return INT2FIX(0);
|
335
|
+
if (FIXNUM_P(y)) {
|
336
|
+
if (FIX2LONG(x) > FIX2LONG(y)) return INT2FIX(1);
|
337
|
+
return INT2FIX(-1);
|
338
|
+
}
|
339
|
+
/* modified */
|
340
|
+
return rb_big_cmp(rb_int2big(FIX2LONG(x)), y);
|
341
|
+
}
|
342
|
+
|
343
|
+
static VALUE
|
344
|
+
fix_odd_p(VALUE num)
|
345
|
+
{
|
346
|
+
if (num & 2) {
|
347
|
+
return Qtrue;
|
348
|
+
}
|
349
|
+
return Qfalse;
|
350
|
+
}
|