srawlins-gmp 0.1.4.2 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +21 -18
- data/ext/gmp.c +17 -216
- data/ext/gmpf.h +11 -309
- data/ext/gmpq.h +8 -482
- data/ext/gmpz.h +5 -818
- metadata +1 -1
data/ext/gmpz.h
CHANGED
@@ -1,283 +1,13 @@
|
|
1
|
+
#ifndef _GMPZ_H_
|
2
|
+
#define _GMPZ_H_
|
3
|
+
|
1
4
|
/*
|
2
5
|
* gmpz.h
|
3
6
|
*
|
4
7
|
* This file contains GMP::Z method definitions.
|
5
8
|
*/
|
6
9
|
|
7
|
-
|
8
|
-
* call-seq: +(other)
|
9
|
-
*
|
10
|
-
* Adds this GMP::Z to other. Other can be
|
11
|
-
* * GMP::Z
|
12
|
-
* * Fixnum
|
13
|
-
* * GMP::Q
|
14
|
-
* * GMP::F
|
15
|
-
* * Bignum
|
16
|
-
*/
|
17
|
-
static VALUE r_gmpz_add(VALUE self, VALUE arg)
|
18
|
-
{
|
19
|
-
MP_INT *self_val, *arg_val, *res_val;
|
20
|
-
VALUE res;
|
21
|
-
|
22
|
-
mpz_get_struct(self,self_val);
|
23
|
-
|
24
|
-
if (GMPZ_P(arg)) {
|
25
|
-
mpz_get_struct(arg,arg_val);
|
26
|
-
mpz_make_struct_init(res, res_val);
|
27
|
-
mpz_add (res_val, self_val, arg_val);
|
28
|
-
} else if (FIXNUM_P(arg)) {
|
29
|
-
mpz_make_struct_init(res, res_val);
|
30
|
-
if (FIX2INT(arg) > 0)
|
31
|
-
mpz_add_ui (res_val, self_val, FIX2INT(arg));
|
32
|
-
else
|
33
|
-
mpz_sub_ui (res_val, self_val, -FIX2INT(arg));
|
34
|
-
} else if (GMPQ_P(arg)) {
|
35
|
-
return r_gmpq_add(arg, self);
|
36
|
-
} else if (GMPF_P(arg)) {
|
37
|
-
return r_gmpf_add(arg, self);
|
38
|
-
} else if (BIGNUM_P(arg)) {
|
39
|
-
mpz_make_struct_init(res, res_val);
|
40
|
-
mpz_init (res_val);
|
41
|
-
mpz_set_bignum (res_val, arg);
|
42
|
-
mpz_add (res_val, res_val, self_val);
|
43
|
-
} else {
|
44
|
-
typeerror (ZQFXB);
|
45
|
-
}
|
46
|
-
return res;
|
47
|
-
}
|
48
|
-
|
49
|
-
static VALUE r_gmpz_add_self(VALUE self, VALUE arg)
|
50
|
-
{
|
51
|
-
MP_INT *self_val, *arg_val;
|
52
|
-
|
53
|
-
mpz_get_struct(self,self_val);
|
54
|
-
|
55
|
-
if (GMPZ_P(arg)) {
|
56
|
-
mpz_get_struct(arg,arg_val);
|
57
|
-
mpz_add (self_val, self_val, arg_val);
|
58
|
-
} else if (FIXNUM_P(arg)) {
|
59
|
-
if (FIX2INT(arg) > 0)
|
60
|
-
mpz_add_ui (self_val, self_val, FIX2INT(arg));
|
61
|
-
else
|
62
|
-
mpz_sub_ui (self_val, self_val, -FIX2INT(arg));
|
63
|
-
} else if (BIGNUM_P(arg)) {
|
64
|
-
mpz_temp_from_bignum (arg_val, arg);
|
65
|
-
mpz_add (self_val, self_val, arg_val);
|
66
|
-
mpz_temp_free (arg_val);
|
67
|
-
} else {
|
68
|
-
typeerror (ZXB);
|
69
|
-
}
|
70
|
-
return Qnil;
|
71
|
-
}
|
72
|
-
|
73
|
-
static VALUE r_gmpz_sub(VALUE self, VALUE arg)
|
74
|
-
{
|
75
|
-
MP_RAT *res_val_q, *arg_val_q;
|
76
|
-
MP_INT *self_val, *arg_val, *res_val;
|
77
|
-
MP_FLOAT *arg_val_f, *res_val_f;
|
78
|
-
VALUE res;
|
79
|
-
unsigned long prec;
|
80
|
-
|
81
|
-
mpz_get_struct(self,self_val);
|
82
|
-
|
83
|
-
if (GMPZ_P(arg)) {
|
84
|
-
mpz_make_struct_init(res, res_val);
|
85
|
-
mpz_get_struct(arg,arg_val);
|
86
|
-
mpz_sub (res_val, self_val, arg_val);
|
87
|
-
} else if (FIXNUM_P(arg)) {
|
88
|
-
mpz_make_struct_init(res, res_val);
|
89
|
-
if (FIX2INT(arg) > 0)
|
90
|
-
mpz_sub_ui (res_val, self_val, FIX2INT(arg));
|
91
|
-
else
|
92
|
-
mpz_add_ui (res_val, self_val, -FIX2INT(arg));
|
93
|
-
} else if (GMPQ_P(arg)) {
|
94
|
-
mpq_make_struct_init(res, res_val_q);
|
95
|
-
mpq_get_struct(arg,arg_val_q);
|
96
|
-
mpz_set (mpq_denref(res_val_q), mpq_denref(arg_val_q));
|
97
|
-
mpz_mul (mpq_numref(res_val_q), mpq_denref(arg_val_q), self_val);
|
98
|
-
mpz_sub (mpq_numref(res_val_q), mpq_numref(res_val_q), mpq_numref(arg_val_q));
|
99
|
-
} else if (GMPF_P(arg)) {
|
100
|
-
mpf_get_struct_prec (arg, arg_val_f, prec);
|
101
|
-
mpf_make_struct_init(res, res_val_f, prec);
|
102
|
-
mpf_set_z (res_val_f, self_val);
|
103
|
-
mpf_sub (res_val_f, res_val_f, arg_val_f);
|
104
|
-
} else if (BIGNUM_P(arg)) {
|
105
|
-
mpz_make_struct_init(res, res_val);
|
106
|
-
mpz_set_bignum (res_val, arg);
|
107
|
-
mpz_sub (res_val, self_val, res_val);
|
108
|
-
} else {
|
109
|
-
typeerror (ZQFXB);
|
110
|
-
}
|
111
|
-
return res;
|
112
|
-
}
|
113
|
-
|
114
|
-
static VALUE r_gmpz_sub_self(VALUE self, VALUE arg)
|
115
|
-
{
|
116
|
-
MP_INT *self_val, *arg_val;
|
117
|
-
|
118
|
-
mpz_get_struct(self,self_val);
|
119
|
-
|
120
|
-
if (GMPZ_P(arg)) {
|
121
|
-
mpz_get_struct(arg, arg_val);
|
122
|
-
mpz_sub (self_val, self_val, arg_val);
|
123
|
-
} else if (FIXNUM_P(arg)) {
|
124
|
-
if (FIX2INT(arg) > 0)
|
125
|
-
mpz_sub_ui (self_val, self_val, FIX2INT(arg));
|
126
|
-
else
|
127
|
-
mpz_add_ui (self_val, self_val, -FIX2INT(arg));
|
128
|
-
} else if (BIGNUM_P(arg)) {
|
129
|
-
mpz_temp_from_bignum(arg_val, arg);
|
130
|
-
mpz_sub (self_val, self_val, arg_val);
|
131
|
-
mpz_temp_free (arg_val);
|
132
|
-
} else {
|
133
|
-
typeerror (ZXB);
|
134
|
-
}
|
135
|
-
return Qnil;
|
136
|
-
}
|
137
|
-
|
138
|
-
static VALUE r_gmpz_mul(VALUE self, VALUE arg)
|
139
|
-
{
|
140
|
-
MP_INT *self_val, *arg_val, *res_val;
|
141
|
-
VALUE res;
|
142
|
-
|
143
|
-
mpz_get_struct(self,self_val);
|
144
|
-
|
145
|
-
if (GMPZ_P(arg)) {
|
146
|
-
mpz_make_struct_init(res, res_val);
|
147
|
-
mpz_get_struct(arg,arg_val);
|
148
|
-
mpz_mul (res_val, self_val, arg_val);
|
149
|
-
} else if (FIXNUM_P(arg)) {
|
150
|
-
mpz_make_struct_init(res, res_val);
|
151
|
-
mpz_mul_si (res_val, self_val, FIX2INT(arg));
|
152
|
-
} else if (GMPQ_P(arg)) {
|
153
|
-
return r_gmpq_mul(arg, self);
|
154
|
-
} else if (GMPF_P(arg)) {
|
155
|
-
return r_gmpf_mul(arg, self);
|
156
|
-
} else if (BIGNUM_P(arg)) {
|
157
|
-
mpz_make_struct_init(res, res_val);
|
158
|
-
mpz_set_bignum (res_val, arg);
|
159
|
-
mpz_mul (res_val, res_val, self_val);
|
160
|
-
} else {
|
161
|
-
typeerror (ZQFXB);
|
162
|
-
}
|
163
|
-
return res;
|
164
|
-
}
|
165
|
-
|
166
|
-
static VALUE r_gmpz_div(VALUE self, VALUE arg)
|
167
|
-
{
|
168
|
-
MP_INT *self_val, *arg_val_z, *tmp_z;
|
169
|
-
MP_RAT *arg_val_q, *res_val_q;
|
170
|
-
MP_FLOAT *arg_val_f, *res_val_f;
|
171
|
-
VALUE res;
|
172
|
-
unsigned int prec;
|
173
|
-
|
174
|
-
mpz_get_struct(self,self_val);
|
175
|
-
|
176
|
-
if (GMPZ_P(arg)) {
|
177
|
-
mpz_get_struct(arg, arg_val_z);
|
178
|
-
if (mpz_cmp_ui(arg_val_z, 0) == 0)
|
179
|
-
rb_raise (rb_eZeroDivError, "divided by 0");
|
180
|
-
mpq_make_struct_init(res, res_val_q);
|
181
|
-
mpq_set_num (res_val_q, self_val);
|
182
|
-
mpq_set_den (res_val_q, arg_val_z);
|
183
|
-
mpq_canonicalize (res_val_q);
|
184
|
-
} else if (FIXNUM_P(arg)) {
|
185
|
-
if (FIX2INT(arg) == 0)
|
186
|
-
rb_raise (rb_eZeroDivError, "divided by 0");
|
187
|
-
mpq_make_struct_init(res, res_val_q);
|
188
|
-
mpq_set_num (res_val_q, self_val);
|
189
|
-
mpz_set_ui (mpq_denref(res_val_q), FIX2INT(arg));
|
190
|
-
mpq_canonicalize (res_val_q);
|
191
|
-
} else if (GMPQ_P(arg)) {
|
192
|
-
mpq_get_struct(arg, arg_val_q);
|
193
|
-
if (mpz_cmp_ui(mpq_numref(arg_val_q), 0) == 0)
|
194
|
-
rb_raise (rb_eZeroDivError, "divided by 0");
|
195
|
-
mpz_temp_init(tmp_z);
|
196
|
-
mpq_make_struct_init(res, res_val_q);
|
197
|
-
mpz_gcd (tmp_z, mpq_numref(arg_val_q), self_val);
|
198
|
-
mpz_divexact (mpq_numref(res_val_q), self_val, tmp_z);
|
199
|
-
mpz_divexact (mpq_denref(res_val_q), mpq_numref(arg_val_q), tmp_z);
|
200
|
-
mpz_mul (mpq_numref(res_val_q), mpq_numref(res_val_q), mpq_denref(arg_val_q));
|
201
|
-
mpz_temp_free(tmp_z);
|
202
|
-
} else if (GMPF_P(arg)) {
|
203
|
-
mpf_get_struct_prec (arg, arg_val_f, prec);
|
204
|
-
mpf_make_struct_init(res, res_val_f, prec);
|
205
|
-
mpf_set_z (res_val_f, self_val);
|
206
|
-
mpf_div (res_val_f, res_val_f, arg_val_f);
|
207
|
-
} else if (BIGNUM_P(arg)) {
|
208
|
-
mpq_make_struct_init(res, res_val_q);
|
209
|
-
mpz_set_bignum (mpq_denref(res_val_q), arg);
|
210
|
-
if (mpz_cmp_ui(mpq_denref(res_val_q), 0) == 0)
|
211
|
-
rb_raise (rb_eZeroDivError, "divided by 0");
|
212
|
-
mpq_set_num (res_val_q, self_val);
|
213
|
-
mpq_canonicalize (res_val_q);
|
214
|
-
} else {
|
215
|
-
typeerror (ZQFXB);
|
216
|
-
}
|
217
|
-
return res;
|
218
|
-
}
|
219
|
-
|
220
|
-
static VALUE r_gmpz_setbit(VALUE self, VALUE bitnr, VALUE set_to)
|
221
|
-
{
|
222
|
-
MP_INT *self_val;
|
223
|
-
int bitnr_val;
|
224
|
-
|
225
|
-
mpz_get_struct(self, self_val);
|
226
|
-
|
227
|
-
if (FIXNUM_P(bitnr)) {
|
228
|
-
bitnr_val = FIX2INT (bitnr);
|
229
|
-
} else {
|
230
|
-
typeerror_as(X, "index");
|
231
|
-
}
|
232
|
-
if (RTEST(set_to)) {
|
233
|
-
mpz_setbit (self_val, bitnr_val);
|
234
|
-
} else {
|
235
|
-
mpz_clrbit (self_val, bitnr_val);
|
236
|
-
}
|
237
|
-
return Qnil;
|
238
|
-
}
|
239
|
-
|
240
|
-
static VALUE r_gmpz_getbit(VALUE self, VALUE bitnr)
|
241
|
-
{
|
242
|
-
MP_INT *self_val;
|
243
|
-
int bitnr_val;
|
244
|
-
mpz_get_struct(self, self_val);
|
245
|
-
if (FIXNUM_P(bitnr)) {
|
246
|
-
bitnr_val = FIX2INT (bitnr);
|
247
|
-
} else {
|
248
|
-
typeerror_as(X, "index");
|
249
|
-
}
|
250
|
-
return mpz_tstbit(self_val, bitnr_val)?Qtrue:Qfalse;
|
251
|
-
}
|
252
|
-
|
253
|
-
static VALUE r_gmpz_scan0(VALUE self, VALUE bitnr)
|
254
|
-
{
|
255
|
-
MP_INT *self_val;
|
256
|
-
int bitnr_val;
|
257
|
-
mpz_get_struct(self, self_val);
|
258
|
-
if (FIXNUM_P(bitnr)) {
|
259
|
-
bitnr_val = FIX2INT (bitnr);
|
260
|
-
} else {
|
261
|
-
typeerror_as(X, "index");
|
262
|
-
}
|
263
|
-
return INT2FIX(mpz_scan0(self_val, bitnr_val));
|
264
|
-
}
|
265
|
-
|
266
|
-
static VALUE r_gmpz_scan1(VALUE self, VALUE bitnr)
|
267
|
-
{
|
268
|
-
MP_INT *self_val;
|
269
|
-
int bitnr_val;
|
270
|
-
|
271
|
-
mpz_get_struct(self, self_val);
|
272
|
-
|
273
|
-
if (FIXNUM_P(bitnr)) {
|
274
|
-
bitnr_val = FIX2INT (bitnr);
|
275
|
-
} else {
|
276
|
-
typeerror_as(X, "index");
|
277
|
-
}
|
278
|
-
|
279
|
-
return INT2FIX(mpz_scan1(self_val, bitnr_val));
|
280
|
-
}
|
10
|
+
#include <ruby_gmp.h>
|
281
11
|
|
282
12
|
#define DEFUN_INT_COND_P(fname,mpz_fname) \
|
283
13
|
static VALUE r_gmpz_##fname(VALUE self) \
|
@@ -287,547 +17,4 @@ static VALUE r_gmpz_##fname(VALUE self) \
|
|
287
17
|
return mpz_fname(self_val)?Qtrue:Qfalse; \
|
288
18
|
}
|
289
19
|
|
290
|
-
|
291
|
-
DEFUN_INT_COND_P(is_odd,mpz_odd_p)
|
292
|
-
DEFUN_INT_COND_P(is_square,mpz_perfect_square_p)
|
293
|
-
DEFUN_INT_COND_P(is_power,mpz_perfect_power_p)
|
294
|
-
|
295
|
-
static VALUE r_gmpz_sgn(VALUE self)
|
296
|
-
{
|
297
|
-
MP_INT *self_val;
|
298
|
-
mpz_get_struct(self, self_val);
|
299
|
-
return INT2FIX(mpz_sgn(self_val));
|
300
|
-
}
|
301
|
-
|
302
|
-
static VALUE r_gmpz_powm(VALUE self, VALUE exp, VALUE mod)
|
303
|
-
{
|
304
|
-
MP_INT *self_val, *res_val, *mod_val, *exp_val;
|
305
|
-
VALUE res;
|
306
|
-
int free_mod_val = 0;
|
307
|
-
|
308
|
-
if (GMPZ_P(mod)) {
|
309
|
-
mpz_get_struct(mod, mod_val);
|
310
|
-
if (mpz_sgn(mod_val) <= 0) {
|
311
|
-
rb_raise (rb_eRangeError, "modulus must be positive");
|
312
|
-
}
|
313
|
-
} else if (FIXNUM_P(mod)) {
|
314
|
-
if (FIX2INT(mod) <= 0) {
|
315
|
-
rb_raise (rb_eRangeError, "modulus must be positive");
|
316
|
-
}
|
317
|
-
mpz_temp_alloc (mod_val);
|
318
|
-
mpz_init_set_ui(mod_val, FIX2INT(mod));
|
319
|
-
free_mod_val = 1;
|
320
|
-
} else if (BIGNUM_P(mod)) {
|
321
|
-
mpz_temp_from_bignum (mod_val, mod);
|
322
|
-
if (mpz_sgn(mod_val) <= 0) {
|
323
|
-
mpz_temp_free(mod_val);
|
324
|
-
rb_raise (rb_eRangeError, "modulus must be positive");
|
325
|
-
}
|
326
|
-
free_mod_val = 1;
|
327
|
-
} else {
|
328
|
-
typeerror_as (ZXB, "modulus");
|
329
|
-
}
|
330
|
-
mpz_make_struct_init(res, res_val);
|
331
|
-
mpz_get_struct(self, self_val);
|
332
|
-
|
333
|
-
if (GMPZ_P(exp)) {
|
334
|
-
mpz_get_struct(exp, exp_val);
|
335
|
-
if (mpz_sgn(mod_val) < 0) {
|
336
|
-
rb_raise (rb_eRangeError, "exponent must be nonnegative");
|
337
|
-
}
|
338
|
-
mpz_powm (res_val, self_val, exp_val, mod_val);
|
339
|
-
} else if (FIXNUM_P(exp)) {
|
340
|
-
if (FIX2INT(exp) < 0)
|
341
|
-
{
|
342
|
-
if (free_mod_val)
|
343
|
-
mpz_temp_free(mod_val);
|
344
|
-
rb_raise (rb_eRangeError, "exponent must be nonnegative");
|
345
|
-
}
|
346
|
-
mpz_powm_ui (res_val, self_val, FIX2INT(exp), mod_val);
|
347
|
-
} else if (BIGNUM_P(exp)) {
|
348
|
-
mpz_temp_from_bignum (exp_val, exp);
|
349
|
-
mpz_powm (res_val, self_val, exp_val, mod_val);
|
350
|
-
mpz_temp_free (exp_val);
|
351
|
-
} else {
|
352
|
-
if (free_mod_val)
|
353
|
-
mpz_temp_free(mod_val);
|
354
|
-
typeerror_as (ZXB, "exponent");
|
355
|
-
}
|
356
|
-
if (free_mod_val)
|
357
|
-
mpz_temp_free(mod_val);
|
358
|
-
return res;
|
359
|
-
}
|
360
|
-
|
361
|
-
static VALUE r_gmpz_swap(VALUE self, VALUE arg)
|
362
|
-
{
|
363
|
-
MP_INT *self_val, *arg_val;
|
364
|
-
if (!GMPZ_P(arg)) {
|
365
|
-
rb_raise(rb_eTypeError, "Can't swap GMP::Z with object of other class");
|
366
|
-
}
|
367
|
-
mpz_get_struct(self, self_val);
|
368
|
-
mpz_get_struct(arg, arg_val);
|
369
|
-
mpz_swap(self_val,arg_val);
|
370
|
-
return Qnil;
|
371
|
-
}
|
372
|
-
|
373
|
-
|
374
|
-
#define DEFUN_INT_F_UL(fname,mpz_fname,argname) \
|
375
|
-
static VALUE r_gmpz_##fname(VALUE self, VALUE exp) \
|
376
|
-
{ \
|
377
|
-
MP_INT *self_val, *res_val; \
|
378
|
-
VALUE res; \
|
379
|
-
unsigned long exp_val; \
|
380
|
-
\
|
381
|
-
if (FIXNUM_P(exp)) { \
|
382
|
-
if (FIX2INT (exp) < 0) \
|
383
|
-
rb_raise (rb_eRangeError, argname " out of range"); \
|
384
|
-
exp_val = FIX2INT (exp); \
|
385
|
-
} else if (GMPZ_P(exp)) {\
|
386
|
-
mpz_get_struct (exp, res_val); \
|
387
|
-
if (!mpz_fits_ulong_p (res_val)) \
|
388
|
-
rb_raise (rb_eRangeError, argname " out of range"); \
|
389
|
-
exp_val = mpz_get_ui (res_val); \
|
390
|
-
if (exp_val == 0) \
|
391
|
-
rb_raise (rb_eRangeError, argname " out of range"); \
|
392
|
-
} else { \
|
393
|
-
typeerror_as (ZX, argname); \
|
394
|
-
} \
|
395
|
-
\
|
396
|
-
mpz_make_struct_init(res, res_val); \
|
397
|
-
mpz_get_struct(self, self_val); \
|
398
|
-
mpz_fname(res_val, self_val, exp_val); \
|
399
|
-
\
|
400
|
-
return res; \
|
401
|
-
}
|
402
|
-
|
403
|
-
DEFUN_INT_F_UL(pow,mpz_pow_ui,"exponent")
|
404
|
-
DEFUN_INT_F_UL(shl,mpz_mul_2exp,"shift size")
|
405
|
-
DEFUN_INT_F_UL(fshr,mpz_fdiv_q_2exp,"shift size")
|
406
|
-
DEFUN_INT_F_UL(tshr,mpz_tdiv_q_2exp,"shift size")
|
407
|
-
DEFUN_INT_F_UL(fshrm,mpz_fdiv_r_2exp,"mark size")
|
408
|
-
DEFUN_INT_F_UL(tshrm,mpz_tdiv_r_2exp,"mark size")
|
409
|
-
DEFUN_INT_F_UL(root,mpz_root,"root number")
|
410
|
-
|
411
|
-
static int mpz_cmp_value (MP_INT *OP, VALUE arg)
|
412
|
-
{
|
413
|
-
MP_RAT *arg_val_q;
|
414
|
-
MP_INT *arg_val_z;
|
415
|
-
int res;
|
416
|
-
|
417
|
-
if (GMPZ_P(arg)) {
|
418
|
-
mpz_get_struct(arg,arg_val_z);
|
419
|
-
return mpz_cmp (OP,arg_val_z);
|
420
|
-
} else if (FIXNUM_P(arg)) {
|
421
|
-
return mpz_cmp_si (OP, FIX2INT(arg));
|
422
|
-
} else if (GMPQ_P(arg)) {
|
423
|
-
mpq_get_struct(arg,arg_val_q);
|
424
|
-
mpz_temp_alloc (arg_val_z);
|
425
|
-
mpz_init(arg_val_z);
|
426
|
-
mpz_mul(arg_val_z, OP, mpq_denref(arg_val_q));
|
427
|
-
res = mpz_cmp (arg_val_z, mpq_numref(arg_val_q));
|
428
|
-
mpz_temp_free(arg_val_z);
|
429
|
-
return res;
|
430
|
-
} else if (GMPF_P(arg)) {
|
431
|
-
not_yet;
|
432
|
-
} else if (BIGNUM_P(arg)) {
|
433
|
-
mpz_temp_from_bignum (arg_val_z, arg);
|
434
|
-
res = mpz_cmp (OP, arg_val_z);
|
435
|
-
mpz_temp_free(arg_val_z);
|
436
|
-
return res;
|
437
|
-
} else {
|
438
|
-
typeerror_as (ZQFXB, "exponent");
|
439
|
-
}
|
440
|
-
}
|
441
|
-
|
442
|
-
static VALUE r_gmpz_eq(VALUE self, VALUE arg)
|
443
|
-
{
|
444
|
-
MP_INT *self_val, *arg_val_z;
|
445
|
-
MP_RAT *arg_val_q;
|
446
|
-
|
447
|
-
mpz_get_struct (self, self_val);
|
448
|
-
if (GMPZ_P(arg)) {
|
449
|
-
mpz_get_struct(arg, arg_val_z);
|
450
|
-
return (mpz_cmp (self_val, arg_val_z)==0) ? Qtrue : Qfalse;
|
451
|
-
} else if (FIXNUM_P(arg)) {
|
452
|
-
return (mpz_cmp_si (self_val, FIX2INT(arg))==0) ? Qtrue : Qfalse;
|
453
|
-
} else if (GMPQ_P(arg)) {
|
454
|
-
mpq_get_struct(arg, arg_val_q);
|
455
|
-
if (mpz_cmp_ui(mpq_denref(arg_val_q), 1)==0)
|
456
|
-
return Qfalse;
|
457
|
-
return (mpz_cmp (self_val, mpq_numref(arg_val_q))==0) ? Qtrue : Qfalse;
|
458
|
-
} else if (BIGNUM_P(arg)) {
|
459
|
-
mpz_temp_from_bignum(arg_val_z, arg);
|
460
|
-
if (mpz_cmp (self_val, arg_val_z)==0) {
|
461
|
-
mpz_temp_free(arg_val_z);
|
462
|
-
return Qtrue;
|
463
|
-
} else {
|
464
|
-
mpz_temp_free(arg_val_z);
|
465
|
-
return Qfalse;
|
466
|
-
}
|
467
|
-
} else {
|
468
|
-
return Qfalse;
|
469
|
-
}
|
470
|
-
}
|
471
|
-
|
472
|
-
static VALUE r_gmpz_cmp(VALUE self, VALUE arg)
|
473
|
-
{
|
474
|
-
MP_INT *self_val;
|
475
|
-
int res;
|
476
|
-
mpz_get_struct (self,self_val);
|
477
|
-
res = mpz_cmp_value(self_val, arg);
|
478
|
-
if (res > 0)
|
479
|
-
return INT2FIX(1);
|
480
|
-
else if (res == 0)
|
481
|
-
return INT2FIX(0);
|
482
|
-
else
|
483
|
-
return INT2FIX(-1);
|
484
|
-
}
|
485
|
-
|
486
|
-
#define DEFUN_INT_CMP(name,CMP_OP) \
|
487
|
-
static VALUE r_gmpz_cmp_##name(VALUE self, VALUE arg) \
|
488
|
-
{ \
|
489
|
-
MP_INT *self_val; \
|
490
|
-
mpz_get_struct (self,self_val); \
|
491
|
-
return (mpz_cmp_value(self_val, arg) CMP_OP 0)?Qtrue:Qfalse; \
|
492
|
-
}
|
493
|
-
|
494
|
-
DEFUN_INT_CMP(lt,<)
|
495
|
-
DEFUN_INT_CMP(le,<=)
|
496
|
-
DEFUN_INT_CMP(gt,>)
|
497
|
-
DEFUN_INT_CMP(ge,>=)
|
498
|
-
|
499
|
-
#define DEFUN_INT_DIV(fname,gmp_fname) \
|
500
|
-
static VALUE r_gmpz_##fname(VALUE self, VALUE arg) \
|
501
|
-
{ \
|
502
|
-
MP_INT *self_val, *arg_val, *res_val; \
|
503
|
-
VALUE res; \
|
504
|
-
int arg_val_i; \
|
505
|
-
\
|
506
|
-
mpz_get_struct(self, self_val); \
|
507
|
-
mpz_make_struct_init(res, res_val); \
|
508
|
-
\
|
509
|
-
if (GMPZ_P(arg)) { \
|
510
|
-
mpz_get_struct(arg,arg_val); \
|
511
|
-
if (mpz_cmp_ui(arg_val, 0) == 0) \
|
512
|
-
rb_raise (rb_eZeroDivError, "divided by 0"); \
|
513
|
-
gmp_fname (res_val, self_val, arg_val); \
|
514
|
-
} else if (FIXNUM_P(arg)) { \
|
515
|
-
arg_val_i = FIX2INT(arg); \
|
516
|
-
if (arg_val_i > 0) { \
|
517
|
-
gmp_fname##_ui (res_val, self_val, arg_val_i); \
|
518
|
-
} else if (arg_val_i == 0) { \
|
519
|
-
rb_raise (rb_eZeroDivError, "divided by 0"); \
|
520
|
-
} else { \
|
521
|
-
mpz_neg (res_val, self_val); \
|
522
|
-
gmp_fname##_ui (res_val, self_val, -arg_val_i); \
|
523
|
-
} \
|
524
|
-
} else if (BIGNUM_P(arg)) { \
|
525
|
-
mpz_set_bignum (res_val, arg); \
|
526
|
-
if (mpz_cmp_ui(res_val, 0) == 0) \
|
527
|
-
rb_raise (rb_eZeroDivError, "divided by 0"); \
|
528
|
-
gmp_fname (res_val, self_val, res_val); \
|
529
|
-
} else { \
|
530
|
-
typeerror(ZXB); \
|
531
|
-
} \
|
532
|
-
return res; \
|
533
|
-
}
|
534
|
-
|
535
|
-
DEFUN_INT_DIV(tdiv, mpz_tdiv_q)
|
536
|
-
DEFUN_INT_DIV(tmod, mpz_tdiv_r)
|
537
|
-
DEFUN_INT_DIV(fdiv, mpz_fdiv_q)
|
538
|
-
DEFUN_INT_DIV(fmod, mpz_fdiv_r)
|
539
|
-
DEFUN_INT_DIV(cdiv, mpz_cdiv_q)
|
540
|
-
DEFUN_INT_DIV(cmod, mpz_cdiv_r)
|
541
|
-
|
542
|
-
#define DEFUN_INT2INT(fname,mpz_fname) \
|
543
|
-
static VALUE r_gmpz_##fname(VALUE self) \
|
544
|
-
{ \
|
545
|
-
MP_INT *self_val, *res_val; \
|
546
|
-
VALUE res; \
|
547
|
-
mpz_get_struct(self, self_val); \
|
548
|
-
mpz_make_struct_init(res, res_val); \
|
549
|
-
mpz_fname(res_val, self_val); \
|
550
|
-
return res; \
|
551
|
-
} \
|
552
|
-
\
|
553
|
-
static VALUE r_gmpz_##fname##_self(VALUE self) \
|
554
|
-
{ \
|
555
|
-
MP_INT *self_val; \
|
556
|
-
mpz_get_struct(self, self_val); \
|
557
|
-
mpz_fname(self_val, self_val); \
|
558
|
-
return Qnil; \
|
559
|
-
}
|
560
|
-
|
561
|
-
DEFUN_INT2INT(abs, mpz_abs)
|
562
|
-
DEFUN_INT2INT(neg, mpz_neg)
|
563
|
-
DEFUN_INT2INT(com, mpz_com)
|
564
|
-
DEFUN_INT2INT(sqrt, mpz_sqrt)
|
565
|
-
DEFUN_INT2INT(nextprime, mpz_nextprime)
|
566
|
-
|
567
|
-
/*
|
568
|
-
* call-seq: probab_prime_p(reps)
|
569
|
-
*
|
570
|
-
* Determine whether n is prime. Return 2 if n is definitely prime, return 1 if
|
571
|
-
* n is probably prime (without being certain), or return 0 if n is definitely
|
572
|
-
* composite.
|
573
|
-
*
|
574
|
-
* This function does some trial divisions, then some Miller-Rabin
|
575
|
-
* probabilistic primality tests. reps controls how many such tests are done, 5
|
576
|
-
* to 10 is a reasonable number, more will reduce the chances of a composite
|
577
|
-
* being returned as �probably prime�.
|
578
|
-
*
|
579
|
-
* Miller-Rabin and similar tests can be more properly called compositeness
|
580
|
-
* tests. Numbers which fail are known to be composite but those which pass
|
581
|
-
* might be prime or might be composite. Only a few composites pass, hence
|
582
|
-
* those which pass are considered probably prime.
|
583
|
-
*/
|
584
|
-
static VALUE r_gmpz_is_probab_prime(int argc, VALUE* argv, VALUE self)
|
585
|
-
{
|
586
|
-
MP_INT *self_val;
|
587
|
-
int reps_val;
|
588
|
-
VALUE reps;
|
589
|
-
mpz_get_struct(self, self_val);
|
590
|
-
rb_scan_args(argc, argv, "01", &reps);
|
591
|
-
if(NIL_P(reps)){
|
592
|
-
reps = INT2FIX(5);
|
593
|
-
}
|
594
|
-
if (FIXNUM_P(reps)) {
|
595
|
-
reps_val = FIX2INT (reps);
|
596
|
-
} else {
|
597
|
-
typeerror_as(X, "reps");
|
598
|
-
}
|
599
|
-
return INT2FIX(mpz_probab_prime_p(self_val, reps_val));
|
600
|
-
}
|
601
|
-
|
602
|
-
static VALUE r_gmpz_popcount(VALUE self)
|
603
|
-
{
|
604
|
-
MP_INT *self_val;
|
605
|
-
mpz_get_struct(self, self_val);
|
606
|
-
return INT2FIX(mpz_popcount(self_val));
|
607
|
-
}
|
608
|
-
|
609
|
-
static VALUE r_gmpz_jacobi(VALUE self)
|
610
|
-
{
|
611
|
-
MP_INT *self_val, *res_val;
|
612
|
-
VALUE res;
|
613
|
-
mpz_get_struct(self, self_val);
|
614
|
-
if (mpz_sgn(self_val) != 1)
|
615
|
-
rb_raise(rb_eRangeError, "you can take jacobi symbol only of positive value");
|
616
|
-
if (mpz_even_p(self_val))
|
617
|
-
rb_raise(rb_eRangeError, "you can't take jacobi symbol of even value");
|
618
|
-
mpz_make_struct_init(res, res_val);
|
619
|
-
mpz_jacobi(res_val, self_val);
|
620
|
-
return res;
|
621
|
-
}
|
622
|
-
|
623
|
-
static VALUE r_gmpz_legendre(VALUE self)
|
624
|
-
{
|
625
|
-
MP_INT *self_val, *res_val;
|
626
|
-
VALUE res;
|
627
|
-
mpz_get_struct(self, self_val);
|
628
|
-
if (mpz_sgn(self_val) != 1)
|
629
|
-
rb_raise(rb_eRangeError, "you can take legendre symbol only of positive value");
|
630
|
-
if (mpz_even_p(self_val))
|
631
|
-
rb_raise(rb_eRangeError, "you can't take legendre symbol of even value");
|
632
|
-
mpz_make_struct_init(res, res_val);
|
633
|
-
mpz_legendre(res_val, self_val);
|
634
|
-
return res;
|
635
|
-
}
|
636
|
-
|
637
|
-
#define DEFUN_INT_LOGIC(fname, mpz_fname) \
|
638
|
-
static VALUE r_gmpz_##fname(VALUE self, VALUE arg) \
|
639
|
-
{ \
|
640
|
-
MP_INT *self_val, *arg_val, *res_val; \
|
641
|
-
VALUE res; \
|
642
|
-
\
|
643
|
-
mpz_get_struct(self, self_val); \
|
644
|
-
\
|
645
|
-
mpz_make_struct(res, res_val); \
|
646
|
-
if (GMPZ_P(arg)) { \
|
647
|
-
mpz_get_struct(arg,arg_val); \
|
648
|
-
mpz_init (res_val); \
|
649
|
-
mpz_fname (res_val, self_val, arg_val); \
|
650
|
-
} else if (FIXNUM_P(arg)) { \
|
651
|
-
mpz_init_set_si (res_val, FIX2INT(arg)); \
|
652
|
-
mpz_fname (res_val, self_val, res_val); \
|
653
|
-
} else if (BIGNUM_P(arg)) { \
|
654
|
-
mpz_init (res_val); \
|
655
|
-
mpz_set_bignum (res_val, arg); \
|
656
|
-
mpz_fname (res_val, self_val, res_val); \
|
657
|
-
} else { \
|
658
|
-
typeerror(ZXB); \
|
659
|
-
} \
|
660
|
-
return res; \
|
661
|
-
}
|
662
|
-
|
663
|
-
DEFUN_INT_LOGIC(and, mpz_and)
|
664
|
-
DEFUN_INT_LOGIC(xor, mpz_xor)
|
665
|
-
DEFUN_INT_LOGIC(or, mpz_ior)
|
666
|
-
|
667
|
-
static VALUE r_gmpz_sqrtrem(VALUE self)
|
668
|
-
{
|
669
|
-
MP_INT *self_val, *sqrt_val, *rem_val;
|
670
|
-
VALUE sqrt, rem;
|
671
|
-
|
672
|
-
mpz_get_struct (self, self_val);
|
673
|
-
mpz_make_struct_init(sqrt, sqrt_val);
|
674
|
-
mpz_make_struct_init(rem, rem_val);
|
675
|
-
mpz_sqrtrem (sqrt_val, rem_val, self_val);
|
676
|
-
return rb_assoc_new(sqrt, rem);
|
677
|
-
}
|
678
|
-
|
679
|
-
static VALUE r_gmpz_to_d(VALUE self)
|
680
|
-
{
|
681
|
-
MP_INT *self_val;
|
682
|
-
mpz_get_struct (self, self_val);
|
683
|
-
|
684
|
-
return rb_float_new(mpz_get_d(self_val));
|
685
|
-
}
|
686
|
-
|
687
|
-
#define DEFUN_INT_SINGLETON_UI(fname,mpz_fname) \
|
688
|
-
static VALUE r_gmpzsg_##fname(VALUE klass, VALUE arg) \
|
689
|
-
{ \
|
690
|
-
MP_INT *arg_val_z, *res_val; \
|
691
|
-
unsigned long arg_val_ul; \
|
692
|
-
VALUE res; \
|
693
|
-
\
|
694
|
-
(void)klass; \
|
695
|
-
\
|
696
|
-
if (FIXNUM_P(arg)) { \
|
697
|
-
arg_val_ul = FIX2INT (arg); \
|
698
|
-
} else if (GMPZ_P(arg)) { \
|
699
|
-
mpz_get_struct (arg, arg_val_z); \
|
700
|
-
if (!mpz_fits_ulong_p (arg_val_z)) \
|
701
|
-
rb_raise (rb_eRangeError, "argument out of range"); \
|
702
|
-
arg_val_ul = mpz_get_ui (arg_val_z); \
|
703
|
-
if (arg_val_ul == 0) \
|
704
|
-
rb_raise (rb_eRangeError, "argument out of range"); \
|
705
|
-
} else { \
|
706
|
-
typeerror_as (ZX, "argument"); \
|
707
|
-
} \
|
708
|
-
mpz_make_struct_init(res, res_val); \
|
709
|
-
mpz_fname (res_val, arg_val_ul); \
|
710
|
-
return res; \
|
711
|
-
}
|
712
|
-
|
713
|
-
DEFUN_INT_SINGLETON_UI(fib,mpz_fib_ui)
|
714
|
-
DEFUN_INT_SINGLETON_UI(fac,mpz_fac_ui)
|
715
|
-
|
716
|
-
static VALUE r_gmpzsg_pow(VALUE klass, VALUE base, VALUE exp)
|
717
|
-
{
|
718
|
-
MP_INT *res_val;
|
719
|
-
VALUE res;
|
720
|
-
|
721
|
-
if (FIXNUM_P(base) && FIXNUM_P(exp))
|
722
|
-
{
|
723
|
-
if (FIX2INT(base) < 0)
|
724
|
-
rb_raise (rb_eRangeError, "base must not be negative");
|
725
|
-
if (FIX2INT(exp) < 0)
|
726
|
-
rb_raise (rb_eRangeError, "exponent must not be negative");
|
727
|
-
mpz_make_struct_init (res, res_val);
|
728
|
-
mpz_ui_pow_ui (res_val, base, exp);
|
729
|
-
return res;
|
730
|
-
}
|
731
|
-
return r_gmpz_pow (r_gmpzsg_new(1, &base, klass), exp);
|
732
|
-
}
|
733
|
-
|
734
|
-
static VALUE r_gmpz_remove(VALUE self, VALUE arg)
|
735
|
-
{
|
736
|
-
MP_INT *self_val, *arg_val, *res_val;
|
737
|
-
VALUE res;
|
738
|
-
int free_arg_val = 0;
|
739
|
-
|
740
|
-
mpz_get_struct(self,self_val);
|
741
|
-
|
742
|
-
if (GMPZ_P(arg)) {
|
743
|
-
mpz_get_struct(arg,arg_val);
|
744
|
-
if (mpz_sgn(arg_val) != 1)
|
745
|
-
rb_raise(rb_eRangeError, "argument must be positive");
|
746
|
-
} else if (FIXNUM_P(arg)) {
|
747
|
-
if (FIX2INT(arg) <= 0)
|
748
|
-
rb_raise(rb_eRangeError, "argument must be positive");
|
749
|
-
mpz_temp_alloc(arg_val);
|
750
|
-
mpz_init_set_ui(arg_val, FIX2INT(arg));
|
751
|
-
} else if (BIGNUM_P(arg)) {
|
752
|
-
mpz_temp_from_bignum(arg_val, arg);
|
753
|
-
if (mpz_sgn(arg_val) != 1) {
|
754
|
-
mpz_temp_free (arg_val);
|
755
|
-
rb_raise(rb_eRangeError, "argument must be positive");
|
756
|
-
}
|
757
|
-
} else {
|
758
|
-
typeerror(ZXB);
|
759
|
-
}
|
760
|
-
|
761
|
-
mpz_make_struct_init (res, res_val);
|
762
|
-
mpz_remove (res_val, self_val, arg_val);
|
763
|
-
|
764
|
-
if (free_arg_val)
|
765
|
-
mpz_temp_free(arg_val);
|
766
|
-
|
767
|
-
return res;
|
768
|
-
}
|
769
|
-
|
770
|
-
static VALUE r_gmpz_to_i(VALUE self)
|
771
|
-
{
|
772
|
-
MP_INT *self_val;
|
773
|
-
char *str;
|
774
|
-
VALUE res;
|
775
|
-
|
776
|
-
mpz_get_struct(self, self_val);
|
777
|
-
if (mpz_fits_slong_p(self_val))
|
778
|
-
return rb_int2inum(mpz_get_si(self_val));
|
779
|
-
str = mpz_get_str(NULL, 0, self_val);
|
780
|
-
res = rb_cstr2inum (str, 10);
|
781
|
-
free (str);
|
782
|
-
return res;
|
783
|
-
}
|
784
|
-
|
785
|
-
static VALUE r_gmpz_cmpabs(VALUE self, VALUE arg)
|
786
|
-
{
|
787
|
-
MP_INT *arg_val_z, *self_val;
|
788
|
-
MP_RAT *arg_val_q;
|
789
|
-
int res;
|
790
|
-
|
791
|
-
mpz_get_struct (self, self_val);
|
792
|
-
|
793
|
-
if (GMPZ_P(arg)) {
|
794
|
-
mpz_get_struct(arg,arg_val_z);
|
795
|
-
return INT2FIX(mpz_cmpabs (self_val, arg_val_z));
|
796
|
-
} else if (FIXNUM_P(arg)) {
|
797
|
-
if (FIX2INT(arg) >= 0)
|
798
|
-
return INT2FIX(mpz_cmpabs_ui (self_val, FIX2INT(arg)));
|
799
|
-
else
|
800
|
-
return INT2FIX(mpz_cmpabs_ui (self_val, -FIX2INT(arg)));
|
801
|
-
} else if (GMPQ_P(arg)) {
|
802
|
-
mpq_get_struct(arg,arg_val_q);
|
803
|
-
mpz_temp_alloc (arg_val_z);
|
804
|
-
mpz_init(arg_val_z);
|
805
|
-
mpz_mul(arg_val_z, self_val, mpq_denref(arg_val_q));
|
806
|
-
res = mpz_cmpabs (arg_val_z, mpq_numref(arg_val_q));
|
807
|
-
mpz_temp_free(arg_val_z);
|
808
|
-
return INT2FIX(res);
|
809
|
-
} else if (GMPF_P(arg)) {
|
810
|
-
not_yet;
|
811
|
-
} else if (BIGNUM_P(arg)) {
|
812
|
-
mpz_temp_from_bignum (arg_val_z, arg);
|
813
|
-
res = mpz_cmpabs (self_val, arg_val_z);
|
814
|
-
mpz_temp_free(arg_val_z);
|
815
|
-
return INT2FIX(res);
|
816
|
-
} else {
|
817
|
-
typeerror(ZQFXB);
|
818
|
-
}
|
819
|
-
}
|
820
|
-
|
821
|
-
static VALUE r_gmpz_to_s(VALUE self)
|
822
|
-
{
|
823
|
-
MP_INT *self_val;
|
824
|
-
char *str;
|
825
|
-
VALUE res;
|
826
|
-
|
827
|
-
Data_Get_Struct(self, MP_INT, self_val);
|
828
|
-
str = mpz_get_str(NULL, 10, self_val);
|
829
|
-
res = rb_str_new2(str);
|
830
|
-
free (str);
|
831
|
-
|
832
|
-
return res;
|
833
|
-
}
|
20
|
+
#endif
|