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.
Files changed (6) hide show
  1. data/README.rdoc +21 -18
  2. data/ext/gmp.c +17 -216
  3. data/ext/gmpf.h +11 -309
  4. data/ext/gmpq.h +8 -482
  5. data/ext/gmpz.h +5 -818
  6. 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
- DEFUN_INT_COND_P(is_even,mpz_even_p)
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