gmp 0.6.47 → 0.7.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +21 -1
- data/README.markdown +29 -9
- data/ext/extconf.rb +8 -0
- data/ext/gmp.c +7 -7
- data/ext/gmpf.c +620 -139
- data/ext/gmpq.c +218 -90
- data/ext/gmprandstate.c +57 -53
- data/ext/gmpz.c +492 -440
- data/ext/mprnd.c +44 -35
- data/ext/ruby_gmp.h +6 -6
- data/manual.pdf +0 -0
- data/manual.tex +2 -2
- data/test/mpfr_thypot.rb +60 -0
- data/test/tc_cmp.rb +1 -1
- data/test/tc_constants.rb +1 -1
- data/test/tc_division.rb +1 -1
- data/test/tc_f_abs_neg.rb +1 -1
- data/test/tc_f_arithmetics_coersion.rb +1 -1
- data/test/tc_f_precision.rb +2 -1
- data/test/tc_f_to_s.rb +1 -1
- data/test/tc_hashes.rb +1 -4
- data/test/tc_mpfr_cmp.rb +1 -1
- data/test/tc_mpfr_constants.rb +1 -1
- data/test/tc_mpfr_functions.rb +43 -10
- data/test/tc_mpfr_inf_nan_zero.rb +1 -1
- data/test/tc_mpfr_integer.rb +1 -1
- data/test/tc_mpfr_new_rounding.rb +24 -1
- data/test/tc_mpfr_pow.rb +17 -0
- data/test/tc_mpfr_random.rb +1 -1
- data/test/tc_mpfr_rounding.rb +1 -1
- data/test/tc_q.rb +53 -32
- data/test/tc_q_basic.rb +1 -1
- data/test/{tc_floor_ceil_truncate.rb → tc_q_floor_ceil_truncate.rb} +2 -2
- data/test/tc_q_num_den.rb +18 -0
- data/test/tc_random.rb +1 -4
- data/test/tc_sgn_neg_abs.rb +1 -1
- data/test/tc_swap.rb +1 -1
- data/test/tc_z.rb +1 -1
- data/test/tc_z_addmul.rb +1 -1
- data/test/tc_z_basic.rb +3 -2
- data/test/tc_z_exponentiation.rb +5 -5
- data/test/tc_z_export_import.rb +1 -1
- data/test/{tc_fib_fac_nextprime.rb → tc_z_fib_fac_nextprime.rb} +1 -1
- data/test/tc_z_functional_mappings.rb +2 -2
- data/test/tc_z_gcd_lcm_invert.rb +1 -1
- data/test/tc_z_hamdist.rb +1 -1
- data/test/tc_z_io.rb +2 -1
- data/test/tc_z_jac_leg_rem.rb +1 -1
- data/test/tc_z_logic.rb +1 -1
- data/test/{tc_logical_roots.rb → tc_z_logical_roots.rb} +7 -7
- data/test/tc_z_shifts_last_bits.rb +2 -2
- data/test/tc_z_submul.rb +1 -1
- data/test/tc_z_to_dis.rb +1 -1
- data/test/{tc_zerodivisionexceptions.rb → tc_zero_division_exceptions.rb} +2 -2
- data/test/unit_tests.rb +30 -17
- metadata +16 -16
- data/INSTALL +0 -4
data/ext/gmprandstate.c
CHANGED
@@ -7,19 +7,19 @@
|
|
7
7
|
*
|
8
8
|
* GMP Multiple Precision Integer.
|
9
9
|
*
|
10
|
-
* Instances of this class can store variables of the type gmp_randstate_t
|
10
|
+
* Instances of this class can store variables of the type `gmp_randstate_t`.
|
11
11
|
* This class also contains many methods that act as the functions for
|
12
|
-
* gmp_randstate_t variables, as well as a few methods that attempt to make
|
12
|
+
* `gmp_randstate_t` variables, as well as a few methods that attempt to make
|
13
13
|
* this library more Ruby-ish.
|
14
14
|
*
|
15
15
|
* The following list is just a simple checklist for me, really. A better
|
16
16
|
* reference should be found in the rdocs.
|
17
17
|
*
|
18
|
-
*
|
19
|
-
*
|
20
|
-
*
|
21
|
-
*
|
22
|
-
*
|
18
|
+
* Ruby method C Extension function GMP function
|
19
|
+
* new r_gmprandstatesg_new gmp_randinit_default
|
20
|
+
* seed r_gmprandstate_seed gmp_randseed
|
21
|
+
* \--- \------------------ gmp_randseed_ui
|
22
|
+
* urandomb r_gmprandstate_urandomb mpz_urandomb
|
23
23
|
*/
|
24
24
|
|
25
25
|
/**********************************************************************
|
@@ -34,8 +34,8 @@
|
|
34
34
|
* GMP::RandState.new(:lc_2exp_size, size) #=> uses gmp_randinit_lc_2exp_size
|
35
35
|
*
|
36
36
|
* Initializes a new Random State object. Multiple GMP::RandState objects can
|
37
|
-
* be instantiated. They may use different generators and the states
|
38
|
-
*
|
37
|
+
* be instantiated. They may use different generators and the states are kept
|
38
|
+
* separate.
|
39
39
|
*/
|
40
40
|
VALUE r_gmprandstatesg_new(int argc, VALUE *argv, VALUE klass)
|
41
41
|
{
|
@@ -43,7 +43,7 @@ VALUE r_gmprandstatesg_new(int argc, VALUE *argv, VALUE klass)
|
|
43
43
|
VALUE rs;
|
44
44
|
VALUE algorithm, arg2, arg3, arg4;
|
45
45
|
ID algorithm_id = rb_intern("default");
|
46
|
-
MP_INT *a_val;
|
46
|
+
MP_INT *a_val = NULL;
|
47
47
|
unsigned long c_val, m2exp_val;
|
48
48
|
unsigned long size_val;
|
49
49
|
int free_a_val = 0;
|
@@ -62,11 +62,11 @@ VALUE r_gmprandstatesg_new(int argc, VALUE *argv, VALUE klass)
|
|
62
62
|
if (algorithm_id == default_algorithm ||
|
63
63
|
algorithm_id == mt_algorithm) {
|
64
64
|
if (argc > 1)
|
65
|
-
rb_raise(rb_eArgError, "wrong
|
65
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
|
66
66
|
gmp_randinit_default(rs_val);
|
67
67
|
} else if (algorithm_id == lc_2exp_algorithm) {
|
68
68
|
if (argc != 4)
|
69
|
-
rb_raise(rb_eArgError, "wrong
|
69
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 4)", argc);
|
70
70
|
if (GMPZ_P(arg2)) {
|
71
71
|
mpz_get_struct(arg2, a_val);
|
72
72
|
} else if (FIXNUM_P(arg2)) {
|
@@ -84,7 +84,7 @@ VALUE r_gmprandstatesg_new(int argc, VALUE *argv, VALUE klass)
|
|
84
84
|
gmp_randinit_lc_2exp(rs_val, a_val, c_val, m2exp_val);
|
85
85
|
} else if (algorithm_id == lc_2exp_size_algorithm) {
|
86
86
|
if (argc != 2)
|
87
|
-
rb_raise(rb_eArgError, "wrong
|
87
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
|
88
88
|
size_val = NUM2LONG(arg2);
|
89
89
|
if (size_val > 128)
|
90
90
|
rb_raise(rb_eArgError, "size must be within [0..128]");
|
@@ -113,7 +113,7 @@ VALUE r_gmprandstate_initialize(int argc, VALUE *argv, VALUE self)
|
|
113
113
|
* call-seq:
|
114
114
|
* GMP::RandState(arg)
|
115
115
|
*
|
116
|
-
* A convenience method for
|
116
|
+
* A convenience method for GMP::RandState.new(arg).
|
117
117
|
*/
|
118
118
|
VALUE r_gmpmod_randstate(int argc, VALUE *argv, VALUE module)
|
119
119
|
{
|
@@ -132,22 +132,22 @@ VALUE r_gmpmod_randstate(int argc, VALUE *argv, VALUE module)
|
|
132
132
|
*
|
133
133
|
* From the GMP Manual:
|
134
134
|
*
|
135
|
-
* Set an initial seed value into state.
|
135
|
+
* > Set an initial seed value into state.
|
136
136
|
*
|
137
|
-
* The size of a seed determines how many different sequences of random
|
138
|
-
* that it's possible to generate. The
|
139
|
-
* of a given seed compared to the previous seed used, and this
|
140
|
-
* randomness of separate number sequences. The method for
|
141
|
-
* critical if the generated numbers are to be used for
|
142
|
-
* such as generating cryptographic keys.
|
137
|
+
* > The size of a seed determines how many different sequences of random
|
138
|
+
* > numbers that it's possible to generate. The "quality" of the seed is the
|
139
|
+
* > randomness of a given seed compared to the previous seed used, and this
|
140
|
+
* > affects the randomness of separate number sequences. The method for
|
141
|
+
* > choosing a seed is critical if the generated numbers are to be used for
|
142
|
+
* > important applications, such as generating cryptographic keys.
|
143
143
|
*
|
144
|
-
* Traditionally the system time has been used to seed, but care needs to be
|
145
|
-
* taken with this. If an application seeds often and the resolution of the
|
146
|
-
* system clock is low, then the same sequence of numbers might be repeated.
|
147
|
-
* Also, the system time is quite easy to guess, so if unpredictability is
|
148
|
-
* required then it should definitely not be the only source for the seed
|
149
|
-
* value. On some systems there's a special device
|
150
|
-
* random data better suited for use as a seed.
|
144
|
+
* > Traditionally the system time has been used to seed, but care needs to be
|
145
|
+
* > taken with this. If an application seeds often and the resolution of the
|
146
|
+
* > system clock is low, then the same sequence of numbers might be repeated.
|
147
|
+
* > Also, the system time is quite easy to guess, so if unpredictability is
|
148
|
+
* > required then it should definitely not be the only source for the seed
|
149
|
+
* > value. On some systems there's a special device `/dev/random` which
|
150
|
+
* > provides random data better suited for use as a seed.
|
151
151
|
*/
|
152
152
|
VALUE r_gmprandstate_seed(VALUE self, VALUE arg)
|
153
153
|
{
|
@@ -177,18 +177,18 @@ VALUE r_gmprandstate_seed(VALUE self, VALUE arg)
|
|
177
177
|
|
178
178
|
/*
|
179
179
|
* call-seq:
|
180
|
-
* rand_state.urandomb(
|
180
|
+
* rand_state.urandomb(Fixnum)
|
181
181
|
*
|
182
182
|
* From the GMP Manual:
|
183
183
|
*
|
184
|
-
* Generate a uniformly distributed random integer in the range 0 to
|
185
|
-
*
|
184
|
+
* > Generate a uniformly distributed random integer in the range 0 to
|
185
|
+
* > _2^fixnum-1_, inclusive.
|
186
186
|
*/
|
187
187
|
VALUE r_gmprandstate_urandomb(VALUE self, VALUE arg)
|
188
188
|
{
|
189
189
|
MP_RANDSTATE *self_val;
|
190
190
|
MP_INT *res_val;
|
191
|
-
VALUE res;
|
191
|
+
VALUE res = 0;
|
192
192
|
|
193
193
|
mprandstate_get_struct(self,self_val);
|
194
194
|
|
@@ -208,14 +208,14 @@ VALUE r_gmprandstate_urandomb(VALUE self, VALUE arg)
|
|
208
208
|
*
|
209
209
|
* From the GMP Manual:
|
210
210
|
*
|
211
|
-
* Generate a uniformly distributed random integer in the range 0 to
|
212
|
-
* _integer-1_, inclusive. _integer_ can be an instance of GMP::Z,
|
213
|
-
*
|
211
|
+
* > Generate a uniformly distributed random integer in the range 0 to
|
212
|
+
* > _integer-1_, inclusive. _integer_ can be an instance of GMP::Z, Fixnum, or
|
213
|
+
* > Bignum
|
214
214
|
*/
|
215
215
|
VALUE r_gmprandstate_urandomm(VALUE self, VALUE arg)
|
216
216
|
{
|
217
217
|
MP_RANDSTATE *self_val;
|
218
|
-
MP_INT *res_val, *arg_val;
|
218
|
+
MP_INT *res_val, *arg_val = NULL;
|
219
219
|
int free_arg_val = 0;
|
220
220
|
VALUE res;
|
221
221
|
|
@@ -243,20 +243,21 @@ VALUE r_gmprandstate_urandomm(VALUE self, VALUE arg)
|
|
243
243
|
|
244
244
|
/*
|
245
245
|
* call-seq:
|
246
|
-
* rand_state.rrandomb(
|
246
|
+
* rand_state.rrandomb(Fixnum)
|
247
247
|
*
|
248
248
|
* From the GMP Manual:
|
249
249
|
*
|
250
|
-
* Generate a random integer with long strings of zeros and ones in the
|
251
|
-
* representation. Useful for testing functions and algorithms, since
|
252
|
-
* of random numbers have proven to be more likely to trigger
|
253
|
-
* The random number will be in the range 0 to
|
250
|
+
* > Generate a random integer with long strings of zeros and ones in the
|
251
|
+
* > binary representation. Useful for testing functions and algorithms, since
|
252
|
+
* > this kind of random numbers have proven to be more likely to trigger
|
253
|
+
* > corner-case bugs. The random number will be in the range 0 to _2^n-1_,
|
254
|
+
* > inclusive.
|
254
255
|
*/
|
255
256
|
VALUE r_gmprandstate_rrandomb(VALUE self, VALUE arg)
|
256
257
|
{
|
257
258
|
MP_RANDSTATE *self_val;
|
258
259
|
MP_INT *res_val;
|
259
|
-
VALUE res;
|
260
|
+
VALUE res = 0;
|
260
261
|
|
261
262
|
mprandstate_get_struct(self,self_val);
|
262
263
|
|
@@ -282,7 +283,8 @@ VALUE r_gmprandstate_rrandomb(VALUE self, VALUE arg)
|
|
282
283
|
*
|
283
284
|
* From the MPFR Manual:
|
284
285
|
*
|
285
|
-
* Generate a uniformly distributed random float in the interval
|
286
|
+
* > Generate a uniformly distributed random float in the interval
|
287
|
+
* > _0 <= rop < 1_.
|
286
288
|
*/
|
287
289
|
VALUE r_gmprandstate_mpfr_urandomb(int argc, VALUE *argv, VALUE self_val)
|
288
290
|
{
|
@@ -292,18 +294,18 @@ VALUE r_gmprandstate_mpfr_urandomb(int argc, VALUE *argv, VALUE self_val)
|
|
292
294
|
unsigned long prec = 0;
|
293
295
|
|
294
296
|
if (argc > 1)
|
295
|
-
rb_raise (rb_eArgError, "wrong
|
297
|
+
rb_raise (rb_eArgError, "wrong number of arguments (%d for 0 or 1)", argc);
|
296
298
|
|
297
299
|
mprandstate_get_struct (self_val, self);
|
298
300
|
|
299
301
|
if (argc == 1) {
|
300
302
|
if (FIXNUM_P (argv[0])) {
|
301
303
|
if (FIX2INT (argv[0]) < 2)
|
302
|
-
rb_raise (rb_eRangeError, "
|
304
|
+
rb_raise (rb_eRangeError, "precision must be at least 2");
|
303
305
|
|
304
306
|
prec = FIX2INT (argv[0]);
|
305
307
|
} else {
|
306
|
-
rb_raise (rb_eTypeError, "
|
308
|
+
rb_raise (rb_eTypeError, "precision must be a Fixnum");
|
307
309
|
}
|
308
310
|
}
|
309
311
|
|
@@ -323,10 +325,12 @@ VALUE r_gmprandstate_mpfr_urandomb(int argc, VALUE *argv, VALUE self_val)
|
|
323
325
|
*
|
324
326
|
* From the MPFR Manual:
|
325
327
|
*
|
326
|
-
* Generate a uniformly distributed random float. The floating-point number
|
327
|
-
* can be seen as if a random real number is generated according to the
|
328
|
-
* continuous uniform distribution on the interval [0, 1] and then rounded in
|
329
|
-
* the direction RNDN
|
328
|
+
* > Generate a uniformly distributed random float. The floating-point number
|
329
|
+
* > `rop` can be seen as if a random real number is generated according to the
|
330
|
+
* > continuous uniform distribution on the interval [0, 1] and then rounded in
|
331
|
+
* > the direction `RNDN`.
|
332
|
+
*
|
333
|
+
* @since 0.6.47
|
330
334
|
*/
|
331
335
|
VALUE r_gmprandstate_mpfr_urandom(int argc, VALUE *argv, VALUE self_val)
|
332
336
|
{
|
@@ -334,7 +338,7 @@ VALUE r_gmprandstate_mpfr_urandom(int argc, VALUE *argv, VALUE self_val)
|
|
334
338
|
MP_FLOAT *res;
|
335
339
|
mp_rnd_t rnd_mode;
|
336
340
|
VALUE res_val, prec_val, rnd_mode_val;
|
337
|
-
unsigned long int prec;
|
341
|
+
unsigned long int prec = 0;
|
338
342
|
|
339
343
|
mprandstate_get_struct (self_val, self);
|
340
344
|
|
@@ -346,11 +350,11 @@ VALUE r_gmprandstate_mpfr_urandom(int argc, VALUE *argv, VALUE self_val)
|
|
346
350
|
prec = mpfr_get_default_prec();
|
347
351
|
} else if (FIXNUM_P (prec_val)) {
|
348
352
|
if (FIX2INT (prec_val) < 2)
|
349
|
-
rb_raise (rb_eRangeError, "
|
353
|
+
rb_raise (rb_eRangeError, "precision must be at least 2");
|
350
354
|
|
351
355
|
prec = FIX2INT (prec_val);
|
352
356
|
} else {
|
353
|
-
rb_raise (rb_eTypeError, "
|
357
|
+
rb_raise (rb_eTypeError, "precision must be a Fixnum");
|
354
358
|
}
|
355
359
|
|
356
360
|
mpf_make_struct (res_val, res);
|
data/ext/gmpz.c
CHANGED
@@ -11,8 +11,8 @@
|
|
11
11
|
*
|
12
12
|
* GMP Multiple Precision Integer.
|
13
13
|
*
|
14
|
-
* Instances of this class can store variables of the type mpz_t
|
15
|
-
* also contains many methods that act as the functions for mpz_t variables,
|
14
|
+
* Instances of this class can store variables of the type `mpz_t`. This class
|
15
|
+
* also contains many methods that act as the functions for `mpz_t` variables,
|
16
16
|
* as well as a few methods that attempt to make this library more Ruby-ish.
|
17
17
|
*/
|
18
18
|
|
@@ -26,23 +26,23 @@
|
|
26
26
|
* exactly (0) the return argument and (1) self. The second is the same
|
27
27
|
* destructive method.
|
28
28
|
*/
|
29
|
-
#define DEFUN_INT2INT(fname,mpz_fname)
|
30
|
-
static VALUE r_gmpz_##fname(VALUE
|
31
|
-
{
|
32
|
-
MP_INT *
|
33
|
-
VALUE
|
34
|
-
mpz_get_struct(
|
35
|
-
mpz_make_struct_init(
|
36
|
-
mpz_fname(
|
37
|
-
return
|
38
|
-
}
|
39
|
-
|
40
|
-
static VALUE r_gmpz_##fname##_self(VALUE
|
41
|
-
{
|
42
|
-
MP_INT *
|
43
|
-
mpz_get_struct(
|
44
|
-
mpz_fname(
|
45
|
-
return
|
29
|
+
#define DEFUN_INT2INT(fname,mpz_fname) \
|
30
|
+
static VALUE r_gmpz_##fname(VALUE self_val) \
|
31
|
+
{ \
|
32
|
+
MP_INT *self, *res; \
|
33
|
+
VALUE res_val; \
|
34
|
+
mpz_get_struct(self_val, self); \
|
35
|
+
mpz_make_struct_init(res_val, res); \
|
36
|
+
mpz_fname(res, self); \
|
37
|
+
return res_val; \
|
38
|
+
} \
|
39
|
+
\
|
40
|
+
static VALUE r_gmpz_##fname##_self(VALUE self_val) \
|
41
|
+
{ \
|
42
|
+
MP_INT *self; \
|
43
|
+
mpz_get_struct(self_val, self); \
|
44
|
+
mpz_fname(self, self); \
|
45
|
+
return self_val; \
|
46
46
|
}
|
47
47
|
|
48
48
|
/*
|
@@ -51,41 +51,41 @@ static VALUE r_gmpz_##fname##_self(VALUE self) \
|
|
51
51
|
* mpz_t, whose arguments are (0) the return argument, (1) self, and
|
52
52
|
* (2) exp_value. exp must fit into a ulong.
|
53
53
|
*/
|
54
|
-
#define DEFUN_INT_F_UL(fname,mpz_fname,argname)
|
55
|
-
static VALUE r_gmpz_##fname(VALUE
|
56
|
-
{
|
57
|
-
MP_INT *
|
58
|
-
VALUE
|
59
|
-
unsigned long
|
60
|
-
|
61
|
-
if (FIXNUM_P(
|
62
|
-
if (FIX2NUM(
|
63
|
-
rb_raise(rb_eRangeError, argname " out of range");
|
64
|
-
|
65
|
-
} else if (GMPZ_P(
|
66
|
-
mpz_get_struct(
|
67
|
-
if (!mpz_fits_ulong_p(
|
68
|
-
rb_raise(rb_eRangeError, argname " out of range");
|
69
|
-
|
70
|
-
if (
|
71
|
-
rb_raise(rb_eRangeError, argname " out of range");
|
72
|
-
} else {
|
73
|
-
typeerror_as(ZX, argname);
|
74
|
-
}
|
75
|
-
|
76
|
-
mpz_make_struct_init(
|
77
|
-
mpz_get_struct(
|
78
|
-
mpz_fname(
|
79
|
-
|
80
|
-
return
|
81
|
-
}
|
82
|
-
|
83
|
-
#define DEFUN_INT_CMP(name,CMP_OP)
|
84
|
-
static VALUE r_gmpz_cmp_##name(VALUE
|
85
|
-
{
|
86
|
-
MP_INT *
|
87
|
-
mpz_get_struct(self
|
88
|
-
return (mpz_cmp_value(
|
54
|
+
#define DEFUN_INT_F_UL(fname,mpz_fname,argname) \
|
55
|
+
static VALUE r_gmpz_##fname(VALUE self_val, VALUE exp_val) \
|
56
|
+
{ \
|
57
|
+
MP_INT *self, *res; \
|
58
|
+
VALUE res_val; \
|
59
|
+
unsigned long exp = 0; \
|
60
|
+
\
|
61
|
+
if (FIXNUM_P (exp_val)) { \
|
62
|
+
if (FIX2NUM (exp_val) < 0) \
|
63
|
+
rb_raise (rb_eRangeError, argname " out of range"); \
|
64
|
+
exp = FIX2NUM (exp_val); \
|
65
|
+
} else if (GMPZ_P (exp_val)) { \
|
66
|
+
mpz_get_struct (exp_val, res); \
|
67
|
+
if (!mpz_fits_ulong_p (res)) \
|
68
|
+
rb_raise (rb_eRangeError, argname " out of range"); \
|
69
|
+
exp = mpz_get_ui (res); \
|
70
|
+
if (exp == 0) \
|
71
|
+
rb_raise (rb_eRangeError, argname " out of range"); \
|
72
|
+
} else { \
|
73
|
+
typeerror_as (ZX, argname); \
|
74
|
+
} \
|
75
|
+
\
|
76
|
+
mpz_make_struct_init (res_val, res); \
|
77
|
+
mpz_get_struct (self_val, self); \
|
78
|
+
mpz_fname (res, self, exp); \
|
79
|
+
\
|
80
|
+
return res_val; \
|
81
|
+
}
|
82
|
+
|
83
|
+
#define DEFUN_INT_CMP(name,CMP_OP) \
|
84
|
+
static VALUE r_gmpz_cmp_##name(VALUE self_val, VALUE arg_val) \
|
85
|
+
{ \
|
86
|
+
MP_INT *self; \
|
87
|
+
mpz_get_struct (self_val, self); \
|
88
|
+
return (mpz_cmp_value (self, arg_val) CMP_OP 0) ? Qtrue : Qfalse; \
|
89
89
|
}
|
90
90
|
|
91
91
|
#define DEFUN_INT_DIV(fname,gmp_fname) \
|
@@ -93,18 +93,18 @@ static VALUE r_gmpz_##fname(VALUE self, VALUE arg) \
|
|
93
93
|
{ \
|
94
94
|
MP_INT *self_val, *arg_val, *res_val; \
|
95
95
|
VALUE res; \
|
96
|
-
long arg_val_i;
|
96
|
+
long arg_val_i = 0; \
|
97
97
|
\
|
98
|
-
mpz_get_struct(self, self_val);
|
99
|
-
mpz_make_struct_init(res, res_val);
|
98
|
+
mpz_get_struct (self, self_val); \
|
99
|
+
mpz_make_struct_init (res, res_val); \
|
100
100
|
\
|
101
|
-
if (GMPZ_P(arg)) {
|
102
|
-
mpz_get_struct(arg,arg_val);
|
103
|
-
if (mpz_cmp_ui(arg_val, 0) == 0)
|
101
|
+
if (GMPZ_P (arg)) { \
|
102
|
+
mpz_get_struct (arg,arg_val); \
|
103
|
+
if (mpz_cmp_ui (arg_val, 0) == 0) \
|
104
104
|
rb_raise (rb_eZeroDivError, "divided by 0"); \
|
105
105
|
gmp_fname (res_val, self_val, arg_val); \
|
106
|
-
} else if (FIXNUM_P(arg)) {
|
107
|
-
arg_val_i = FIX2NUM(arg);
|
106
|
+
} else if (FIXNUM_P (arg)) { \
|
107
|
+
arg_val_i = FIX2NUM (arg); \
|
108
108
|
if (arg_val_i > 0) { \
|
109
109
|
gmp_fname##_ui (res_val, self_val, arg_val_i); \
|
110
110
|
} else if (arg_val_i == 0) { \
|
@@ -113,13 +113,13 @@ static VALUE r_gmpz_##fname(VALUE self, VALUE arg) \
|
|
113
113
|
mpz_neg (res_val, self_val); \
|
114
114
|
gmp_fname##_ui (res_val, self_val, -arg_val_i); \
|
115
115
|
} \
|
116
|
-
} else if (BIGNUM_P(arg)) {
|
116
|
+
} else if (BIGNUM_P (arg)) { \
|
117
117
|
mpz_set_bignum (res_val, arg); \
|
118
|
-
if (mpz_cmp_ui(res_val, 0) == 0)
|
118
|
+
if (mpz_cmp_ui (res_val, 0) == 0) \
|
119
119
|
rb_raise (rb_eZeroDivError, "divided by 0"); \
|
120
120
|
gmp_fname (res_val, self_val, res_val); \
|
121
121
|
} else { \
|
122
|
-
typeerror(ZXB);
|
122
|
+
typeerror (ZXB); \
|
123
123
|
} \
|
124
124
|
return res; \
|
125
125
|
}
|
@@ -154,8 +154,8 @@ static VALUE r_gmpz_##fname(VALUE self, VALUE arg) \
|
|
154
154
|
static VALUE r_gmpzsg_##fname(VALUE klass, VALUE arg) \
|
155
155
|
{ \
|
156
156
|
MP_INT *arg_val_z, *res_val; \
|
157
|
-
long arg_val_ul; \
|
158
157
|
VALUE res; \
|
158
|
+
long arg_val_ul = 0; \
|
159
159
|
\
|
160
160
|
(void)klass; \
|
161
161
|
\
|
@@ -183,8 +183,8 @@ static VALUE r_gmpzsg_##fname(VALUE klass, VALUE arg) \
|
|
183
183
|
static VALUE r_gmpzsg_##fname(VALUE klass, VALUE arg) \
|
184
184
|
{ \
|
185
185
|
MP_INT *arg_val_z, *res_val_1, *res_val_2; \
|
186
|
-
long arg_val_ul; \
|
187
186
|
VALUE res_1, res_2; \
|
187
|
+
long arg_val_ul = 0; \
|
188
188
|
\
|
189
189
|
(void)klass; \
|
190
190
|
\
|
@@ -213,8 +213,8 @@ static VALUE r_gmpzsg_##fname(VALUE klass, VALUE arg) \
|
|
213
213
|
static VALUE r_gmpzsg_##fname(VALUE klass, VALUE arg1, VALUE arg2) \
|
214
214
|
{ \
|
215
215
|
MP_INT *arg1_val_z, *res_val; \
|
216
|
-
unsigned long arg1_val_ul, arg2_val_ul; \
|
217
216
|
VALUE res; \
|
217
|
+
unsigned long arg1_val_ul = 0, arg2_val_ul = 0; \
|
218
218
|
\
|
219
219
|
(void)klass; \
|
220
220
|
\
|
@@ -306,7 +306,7 @@ static VALUE r_gmpzsg_##fname(VALUE klass, VALUE rop, VALUE op1, VALUE op2) \
|
|
306
306
|
* call-seq:
|
307
307
|
* GMP::Z.add(rop, op1, op2)
|
308
308
|
*
|
309
|
-
*
|
309
|
+
* @todo Document this
|
310
310
|
*/
|
311
311
|
FUNC_MAP__Z_ZUI__TO__Z__RETURNS__VOID(add,mpz_add)
|
312
312
|
FUNC_MAP__Z_ZUI__TO__Z__RETURNS__VOID(addmul,mpz_addmul)
|
@@ -496,8 +496,8 @@ FUNC_MAP__Z_BITCNT__TO__Z__RETURNS__VOID(tdiv_r_2exp,mpz_tdiv_r_2exp)
|
|
496
496
|
*
|
497
497
|
* TODO: Accept Fixnum, Bignum as op1 and just convert to GMP::Z.
|
498
498
|
*/
|
499
|
-
#define FUNC_MAP__Z__TO__Z__RETURNS__VOID(fname,mpz_fname)
|
500
|
-
static VALUE r_gmpzsg_##fname(VALUE klass, VALUE rop, VALUE op1)
|
499
|
+
#define FUNC_MAP__Z__TO__Z__RETURNS__VOID(fname,mpz_fname) \
|
500
|
+
static VALUE r_gmpzsg_##fname(VALUE klass, VALUE rop, VALUE op1) \
|
501
501
|
{ \
|
502
502
|
MP_INT *rop_val, *op1_val; \
|
503
503
|
(void)klass; \
|
@@ -512,7 +512,7 @@ static VALUE r_gmpzsg_##fname(VALUE klass, VALUE rop, VALUE op1) \
|
|
512
512
|
} \
|
513
513
|
mpz_get_struct (op1, op1_val); \
|
514
514
|
\
|
515
|
-
mpz_fname (rop_val, op1_val);
|
515
|
+
mpz_fname (rop_val, op1_val); \
|
516
516
|
\
|
517
517
|
return Qnil; \
|
518
518
|
}
|
@@ -535,7 +535,7 @@ FUNC_MAP__Z__TO__Z__RETURNS__VOID(com,mpz_com)
|
|
535
535
|
static VALUE r_gmpzsg_##fname(VALUE klass, VALUE op1, VALUE op2) \
|
536
536
|
{ \
|
537
537
|
MP_INT *op1_val, *op2_val; \
|
538
|
-
int res;
|
538
|
+
int res = 0; \
|
539
539
|
(void)klass; \
|
540
540
|
\
|
541
541
|
if (! GMPZ_P (op1)) { \
|
@@ -579,7 +579,7 @@ FUNC_MAP__Z_Z__TO__VOID__RETURNS__BOOL(divisible,mpz_divisible)
|
|
579
579
|
#define FUNC_MAP__Z_ZXB_ZXB__TO__VOID__RETURNS__BOOL(fname,mpz_fname) \
|
580
580
|
static VALUE r_gmpzsg_##fname(VALUE klass, VALUE op1, VALUE op2, VALUE op3) \
|
581
581
|
{ \
|
582
|
-
MP_INT *op1_val, *op2_val, *op3_val;
|
582
|
+
MP_INT *op1_val, *op2_val = 0, *op3_val = 0; \
|
583
583
|
int res; \
|
584
584
|
int free_op2_val = 0; \
|
585
585
|
int free_op3_val = 0; \
|
@@ -591,12 +591,12 @@ static VALUE r_gmpzsg_##fname(VALUE klass, VALUE op1, VALUE op2, VALUE op3) \
|
|
591
591
|
mpz_get_struct (op1, op1_val); \
|
592
592
|
\
|
593
593
|
if (FIXNUM_P (op2)) { \
|
594
|
-
if (FIX2NUM (op2) >= 0) {
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
594
|
+
if (FIX2NUM (op2) >= 0 && FIXNUM_P (op3) && FIX2NUM (op3) >= 0) { \
|
595
|
+
/* short circuit and use ..._ui_p */ \
|
596
|
+
res = mpz_fname##_ui_p (op1_val, FIX2NUM (op2), FIX2NUM (op3)); \
|
597
|
+
return (res ? Qtrue : Qfalse); \
|
598
|
+
} \
|
599
|
+
\
|
600
600
|
mpz_temp_alloc (op2_val); \
|
601
601
|
mpz_init_set_si (op2_val, FIX2NUM (op2)); \
|
602
602
|
free_op2_val = 1; \
|
@@ -610,9 +610,9 @@ static VALUE r_gmpzsg_##fname(VALUE klass, VALUE op1, VALUE op2, VALUE op3) \
|
|
610
610
|
} \
|
611
611
|
\
|
612
612
|
if (FIXNUM_P (op3)) { \
|
613
|
-
|
614
|
-
|
615
|
-
|
613
|
+
mpz_temp_alloc (op3_val); \
|
614
|
+
mpz_init_set_si (op3_val, FIX2NUM (op3)); \
|
615
|
+
free_op3_val = 1; \
|
616
616
|
} else if (BIGNUM_P (op3)) { \
|
617
617
|
mpz_temp_from_bignum (op3_val, op3); \
|
618
618
|
free_op3_val = 1; \
|
@@ -637,11 +637,12 @@ FUNC_MAP__Z_ZXB_ZXB__TO__VOID__RETURNS__BOOL(congruent,mpz_congruent)
|
|
637
637
|
**********************************************************************/
|
638
638
|
|
639
639
|
/*
|
640
|
+
* Document-method: GMP::Z.new
|
640
641
|
* call-seq:
|
641
642
|
* GMP::Z.new(value = 0)
|
642
643
|
*
|
643
|
-
* Creates a new GMP::Z integer, with
|
644
|
-
*
|
644
|
+
* Creates a new GMP::Z integer, with `value` as its value, converting where necessary.
|
645
|
+
* `value` must be an instance of one of the following classes:
|
645
646
|
*
|
646
647
|
* * GMP::Z
|
647
648
|
* * Fixnum
|
@@ -666,7 +667,7 @@ VALUE r_gmpzsg_new(int argc, VALUE *argv, VALUE klass)
|
|
666
667
|
(void)klass;
|
667
668
|
|
668
669
|
if (argc > 2)
|
669
|
-
rb_raise(rb_eArgError, "wrong
|
670
|
+
rb_raise(rb_eArgError, "wrong number of arguments (%d for 0, 1, or 2)", argc);
|
670
671
|
|
671
672
|
mpz_make_struct(res, res_val);
|
672
673
|
mpz_init(res_val);
|
@@ -679,11 +680,6 @@ static VALUE r_gmpz_alloc(VALUE klass) {
|
|
679
680
|
MP_INT *z;
|
680
681
|
VALUE obj;
|
681
682
|
|
682
|
-
//mpz_init(z);
|
683
|
-
//obj = Data_Make_Struct(klass, MP_INT, 0, r_gmpz_free, z);
|
684
|
-
//obj = Data_Wrap_Struct(klass, 0, r_gmpz_free, z);
|
685
|
-
// mpz_make_struct_init (z, obj);
|
686
|
-
// mpz_make_struct_init (obj, z);
|
687
683
|
obj = Data_Make_Struct(klass, MP_INT, 0, r_gmpz_free, z);
|
688
684
|
mpz_init (z);
|
689
685
|
|
@@ -695,10 +691,10 @@ VALUE r_gmpz_initialize(int argc, VALUE *argv, VALUE self)
|
|
695
691
|
MP_INT *self_val;
|
696
692
|
int base = 0;
|
697
693
|
|
698
|
-
|
699
|
-
if (argc == 2) {
|
700
|
-
if (STRING_P(argv[0])) {
|
701
|
-
if (FIXNUM_P(argv[1])) {
|
694
|
+
/* Set up the base if 2 arguments are passed */
|
695
|
+
if (argc == 2) { /* only ok if String, Fixnum */
|
696
|
+
if (STRING_P(argv[0])) { /* first arg must be a String */
|
697
|
+
if (FIXNUM_P(argv[1])) { /* second arg must be a Fixnum */
|
702
698
|
base = FIX2INT(argv[1]);
|
703
699
|
if ( base != 0 && ( base < 2 || base > 62) )
|
704
700
|
rb_raise (rb_eRangeError, "base must be either 0 or between 2 and 62");
|
@@ -721,20 +717,20 @@ VALUE r_gmpz_initialize(int argc, VALUE *argv, VALUE self)
|
|
721
717
|
return Qnil;
|
722
718
|
}
|
723
719
|
|
724
|
-
static VALUE r_gmpz_initialize_copy(VALUE
|
725
|
-
MP_INT *
|
720
|
+
static VALUE r_gmpz_initialize_copy(VALUE copy_val, VALUE orig_val) {
|
721
|
+
MP_INT *orig, *copy;
|
726
722
|
|
727
|
-
if (
|
723
|
+
if (copy_val == orig_val) return copy_val;
|
728
724
|
|
729
|
-
if (TYPE(
|
725
|
+
if (TYPE(orig_val) != T_DATA) {
|
730
726
|
rb_raise(rb_eTypeError, "wrong argument type");
|
731
727
|
}
|
732
728
|
|
733
|
-
mpz_get_struct (
|
734
|
-
mpz_get_struct (
|
735
|
-
mpz_set (
|
729
|
+
mpz_get_struct (orig_val, orig);
|
730
|
+
mpz_get_struct (copy_val, copy);
|
731
|
+
mpz_set (copy, orig);
|
736
732
|
|
737
|
-
return
|
733
|
+
return copy_val;
|
738
734
|
}
|
739
735
|
|
740
736
|
/*
|
@@ -763,7 +759,7 @@ void mpz_set_value(MP_INT *target, VALUE source, int base)
|
|
763
759
|
} else if (BIGNUM_P (source)) {
|
764
760
|
mpz_set_bignum (target, source);
|
765
761
|
} else {
|
766
|
-
rb_raise (rb_eTypeError, "Don't know how to convert %s into
|
762
|
+
rb_raise (rb_eTypeError, "Don't know how to convert %s into GMP::Z", rb_class2name (rb_class_of (source)));
|
767
763
|
}
|
768
764
|
}
|
769
765
|
|
@@ -780,6 +776,7 @@ VALUE r_gmpmod_z(int argc, VALUE *argv, VALUE module)
|
|
780
776
|
}
|
781
777
|
|
782
778
|
/*
|
779
|
+
* Document-method: swap
|
783
780
|
* call-seq:
|
784
781
|
* a.swap(b)
|
785
782
|
*
|
@@ -787,15 +784,16 @@ VALUE r_gmpmod_z(int argc, VALUE *argv, VALUE module)
|
|
787
784
|
*
|
788
785
|
* Efficiently swaps the contents of _a_ with _b_. _b_ must be an instance of GMP::Z.
|
789
786
|
*/
|
790
|
-
VALUE r_gmpz_swap(VALUE
|
787
|
+
VALUE r_gmpz_swap(VALUE self_val, VALUE arg_val)
|
791
788
|
{
|
792
|
-
MP_INT *
|
793
|
-
|
789
|
+
MP_INT *self, *arg;
|
790
|
+
|
791
|
+
if (!GMPZ_P(arg_val))
|
794
792
|
rb_raise(rb_eTypeError, "Can't swap GMP::Z with object of other class");
|
795
|
-
|
796
|
-
mpz_get_struct(
|
797
|
-
mpz_get_struct(
|
798
|
-
mpz_swap(
|
793
|
+
|
794
|
+
mpz_get_struct(self_val, self);
|
795
|
+
mpz_get_struct(arg_val, arg);
|
796
|
+
mpz_swap(self, arg);
|
799
797
|
return Qnil;
|
800
798
|
}
|
801
799
|
|
@@ -805,6 +803,7 @@ VALUE r_gmpz_swap(VALUE self, VALUE arg)
|
|
805
803
|
**********************************************************************/
|
806
804
|
|
807
805
|
/*
|
806
|
+
* Document-method: to_i
|
808
807
|
* call-seq:
|
809
808
|
* a.to_i
|
810
809
|
*
|
@@ -815,8 +814,8 @@ VALUE r_gmpz_swap(VALUE self, VALUE arg)
|
|
815
814
|
* Otherwise returns the least significant part of _a_, with the same sign as _a_.
|
816
815
|
*
|
817
816
|
* If _a_ is too big to fit in a Fixnum, the returned result is probably not very useful.
|
818
|
-
* To find out if the value will fit, use the function
|
819
|
-
* (
|
817
|
+
* To find out if the value will fit, use the function `mpz_fits_slong_p`
|
818
|
+
* (**Unimplemented**).
|
820
819
|
*/
|
821
820
|
VALUE r_gmpz_to_i(VALUE self)
|
822
821
|
{
|
@@ -841,6 +840,7 @@ VALUE r_gmpz_to_i(VALUE self)
|
|
841
840
|
}
|
842
841
|
|
843
842
|
/*
|
843
|
+
* Document-method: to_d
|
844
844
|
* call-seq:
|
845
845
|
* a.to_d
|
846
846
|
*
|
@@ -851,8 +851,8 @@ VALUE r_gmpz_to_i(VALUE self)
|
|
851
851
|
* Otherwise returns the least significant part of _a_, with the same sign as _a_.
|
852
852
|
*
|
853
853
|
* If _a_ is too big to fit in a Float, the returned result is probably not very useful.
|
854
|
-
* To find out if the value will fit, use the function
|
855
|
-
* (
|
854
|
+
* To find out if the value will fit, use the function `mpz_fits_slong_p`
|
855
|
+
* (**Unimplemented**).
|
856
856
|
*/
|
857
857
|
VALUE r_gmpz_to_d(VALUE self)
|
858
858
|
{
|
@@ -864,7 +864,6 @@ VALUE r_gmpz_to_d(VALUE self)
|
|
864
864
|
|
865
865
|
/*
|
866
866
|
* Document-method: to_s
|
867
|
-
*
|
868
867
|
* call-seq:
|
869
868
|
* a.to_s(base = 10)
|
870
869
|
* a.to_s(:bin)
|
@@ -872,17 +871,18 @@ VALUE r_gmpz_to_d(VALUE self)
|
|
872
871
|
* a.to_s(:dec)
|
873
872
|
* a.to_s(:hex)
|
874
873
|
*
|
875
|
-
* Returns _a_, as a String. If
|
874
|
+
* Returns _a_, as a String. If `base` is not provided, then the decimal
|
876
875
|
* representation will be returned.
|
877
876
|
*
|
878
877
|
* From the GMP Manual:
|
879
878
|
*
|
880
|
-
* Convert _a_ to a string of digits in base
|
881
|
-
* to 62 or from -2 to -36.
|
879
|
+
* Convert _a_ to a string of digits in base `base`. The `base` argument may
|
880
|
+
* vary from 2 to 62 or from -2 to -36.
|
882
881
|
*
|
883
|
-
* For
|
884
|
-
* digits and upper-case letters are used; for 37..62, digits,
|
885
|
-
* lower-case letters (in that significance order) are
|
882
|
+
* For `base` in the range 2..36, digits and lower-case letters are used; for
|
883
|
+
* -2..-36, digits and upper-case letters are used; for 37..62, digits,
|
884
|
+
* upper-case letters, and lower-case letters (in that significance order) are
|
885
|
+
* used.
|
886
886
|
*/
|
887
887
|
VALUE r_gmpz_to_s(int argc, VALUE *argv, VALUE self_val)
|
888
888
|
{
|
@@ -910,10 +910,12 @@ VALUE r_gmpz_to_s(int argc, VALUE *argv, VALUE self_val)
|
|
910
910
|
**********************************************************************/
|
911
911
|
|
912
912
|
/*
|
913
|
+
* Document-method: +
|
913
914
|
* call-seq:
|
914
915
|
* a + b
|
915
916
|
*
|
916
917
|
* Adds _a_ to _b_. _b_ must be an instance of one of:
|
918
|
+
*
|
917
919
|
* * GMP::Z
|
918
920
|
* * Fixnum
|
919
921
|
* * GMP::Q
|
@@ -923,7 +925,7 @@ VALUE r_gmpz_to_s(int argc, VALUE *argv, VALUE self_val)
|
|
923
925
|
VALUE r_gmpz_add(VALUE self, VALUE arg)
|
924
926
|
{
|
925
927
|
MP_INT *self_val, *arg_val, *res_val;
|
926
|
-
VALUE res;
|
928
|
+
VALUE res = 0;
|
927
929
|
|
928
930
|
mpz_get_struct(self,self_val);
|
929
931
|
|
@@ -957,10 +959,12 @@ VALUE r_gmpz_add(VALUE self, VALUE arg)
|
|
957
959
|
}
|
958
960
|
|
959
961
|
/*
|
962
|
+
* Document-method: add!
|
960
963
|
* call-seq:
|
961
964
|
* a.add!(_b_)
|
962
965
|
*
|
963
966
|
* Adds _a_ to _b_ in-place, setting _a_ to the sum. _b_ must be an instance of one of:
|
967
|
+
*
|
964
968
|
* * GMP::Z
|
965
969
|
* * Fixnum
|
966
970
|
* * GMP::Q
|
@@ -992,10 +996,12 @@ VALUE r_gmpz_add_self(VALUE self, VALUE arg)
|
|
992
996
|
}
|
993
997
|
|
994
998
|
/*
|
999
|
+
* Document-method: -
|
995
1000
|
* call-seq:
|
996
1001
|
* a - b
|
997
1002
|
*
|
998
1003
|
* Subtracts _b_ from _a_. _b_ must be an instance of one of:
|
1004
|
+
*
|
999
1005
|
* * GMP::Z
|
1000
1006
|
* * Fixnum
|
1001
1007
|
* * GMP::Q
|
@@ -1007,8 +1013,8 @@ VALUE r_gmpz_sub(VALUE self, VALUE arg)
|
|
1007
1013
|
MP_RAT *res_val_q, *arg_val_q;
|
1008
1014
|
MP_INT *self_val, *arg_val, *res_val;
|
1009
1015
|
MP_FLOAT *arg_val_f, *res_val_f;
|
1010
|
-
VALUE res;
|
1011
1016
|
unsigned long prec;
|
1017
|
+
VALUE res = 0;
|
1012
1018
|
|
1013
1019
|
mpz_get_struct(self,self_val);
|
1014
1020
|
|
@@ -1044,11 +1050,13 @@ VALUE r_gmpz_sub(VALUE self, VALUE arg)
|
|
1044
1050
|
}
|
1045
1051
|
|
1046
1052
|
/*
|
1053
|
+
* Document-method: sub!
|
1047
1054
|
* call-seq:
|
1048
1055
|
* a.sub!(b)
|
1049
1056
|
*
|
1050
1057
|
* Subtracts _b_ from _a_ in-place, setting _a_ to the difference. _b_ must be an
|
1051
1058
|
* instance of one of:
|
1059
|
+
*
|
1052
1060
|
* * GMP::Z
|
1053
1061
|
* * Fixnum
|
1054
1062
|
* * GMP::Q
|
@@ -1080,10 +1088,12 @@ VALUE r_gmpz_sub_self(VALUE self, VALUE arg)
|
|
1080
1088
|
}
|
1081
1089
|
|
1082
1090
|
/*
|
1091
|
+
* Document-method: *
|
1083
1092
|
* call-seq:
|
1084
1093
|
* a * b
|
1085
1094
|
*
|
1086
1095
|
* Multiplies _a_ with _b_. _a_ must be an instance of one of
|
1096
|
+
*
|
1087
1097
|
* * GMP::Z
|
1088
1098
|
* * Fixnum
|
1089
1099
|
* * GMP::Q
|
@@ -1093,43 +1103,48 @@ VALUE r_gmpz_sub_self(VALUE self, VALUE arg)
|
|
1093
1103
|
VALUE r_gmpz_mul(VALUE self, VALUE arg)
|
1094
1104
|
{
|
1095
1105
|
MP_INT *self_val, *arg_val, *res_val;
|
1096
|
-
VALUE res;
|
1106
|
+
VALUE res = 0;
|
1097
1107
|
|
1098
|
-
mpz_get_struct(self,self_val);
|
1108
|
+
mpz_get_struct (self, self_val);
|
1099
1109
|
|
1100
|
-
if (GMPZ_P(arg)) {
|
1101
|
-
mpz_make_struct_init(res, res_val);
|
1102
|
-
mpz_get_struct(arg,arg_val);
|
1103
|
-
mpz_mul(res_val, self_val, arg_val);
|
1104
|
-
} else if (FIXNUM_P(arg)) {
|
1105
|
-
mpz_make_struct_init(res, res_val);
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
} else if (
|
1110
|
+
if (GMPZ_P (arg)) {
|
1111
|
+
mpz_make_struct_init (res, res_val);
|
1112
|
+
mpz_get_struct (arg,arg_val);
|
1113
|
+
mpz_mul (res_val, self_val, arg_val);
|
1114
|
+
} else if (FIXNUM_P (arg)) {
|
1115
|
+
mpz_make_struct_init (res, res_val);
|
1116
|
+
if (FIX2NUM (arg) >= 0)
|
1117
|
+
mpz_mul_ui (res_val, self_val, FIX2NUM (arg));
|
1118
|
+
else
|
1119
|
+
mpz_mul_si (res_val, self_val, FIX2NUM (arg));
|
1120
|
+
} else if (GMPQ_P (arg)) {
|
1121
|
+
return r_gmpq_mul (arg, self);
|
1122
|
+
} else if (GMPF_P (arg)) {
|
1111
1123
|
#ifndef MPFR
|
1112
|
-
return r_gmpf_mul(arg, self);
|
1124
|
+
return r_gmpf_mul (arg, self);
|
1113
1125
|
#else
|
1114
|
-
return rb_funcall(arg, rb_intern("*"), 1, self);
|
1126
|
+
return rb_funcall (arg, rb_intern ("*"), 1, self);
|
1115
1127
|
#endif
|
1116
|
-
} else if (BIGNUM_P(arg)) {
|
1117
|
-
mpz_make_struct_init(res, res_val);
|
1118
|
-
mpz_set_bignum(res_val, arg);
|
1119
|
-
mpz_mul(res_val, res_val, self_val);
|
1128
|
+
} else if (BIGNUM_P (arg)) {
|
1129
|
+
mpz_make_struct_init (res, res_val);
|
1130
|
+
mpz_set_bignum (res_val, arg);
|
1131
|
+
mpz_mul (res_val, res_val, self_val);
|
1120
1132
|
} else {
|
1121
|
-
typeerror(ZQFXB);
|
1133
|
+
typeerror (ZQFXB);
|
1122
1134
|
}
|
1123
1135
|
return res;
|
1124
1136
|
}
|
1125
1137
|
|
1126
1138
|
/*
|
1139
|
+
* Document-method: addmul!
|
1127
1140
|
* call-seq:
|
1128
1141
|
* a.addmul!(b, c)
|
1129
1142
|
*
|
1130
1143
|
* @since 0.4.19
|
1131
1144
|
*
|
1132
|
-
* Sets _a_ to _a_ plus _b_ times _c_. _b_ and _c_ must each be an instance of
|
1145
|
+
* Sets _a_ to _a_ plus _b_ times _c_. _b_ and _c_ must each be an instance of
|
1146
|
+
* one of
|
1147
|
+
*
|
1133
1148
|
* * GMP::Z
|
1134
1149
|
* * Fixnum
|
1135
1150
|
* * Bignum
|
@@ -1178,6 +1193,7 @@ static VALUE r_gmpz_addmul_self(VALUE self, VALUE b, VALUE c)
|
|
1178
1193
|
}
|
1179
1194
|
|
1180
1195
|
/*
|
1196
|
+
* Document-method: submul!
|
1181
1197
|
* call-seq:
|
1182
1198
|
* a.submul!(b, c)
|
1183
1199
|
*
|
@@ -1193,19 +1209,19 @@ static VALUE r_gmpz_submul_self(VALUE self, VALUE b, VALUE c)
|
|
1193
1209
|
MP_INT *self_val, *b_val, *c_val;
|
1194
1210
|
int free_b_val = 0;
|
1195
1211
|
|
1196
|
-
if (GMPZ_P(b)) {
|
1197
|
-
mpz_get_struct(b, b_val);
|
1198
|
-
} else if (FIXNUM_P(b)) {
|
1199
|
-
mpz_temp_alloc(b_val);
|
1200
|
-
mpz_init_set_si(b_val, FIX2NUM(b));
|
1212
|
+
if (GMPZ_P (b)) {
|
1213
|
+
mpz_get_struct (b, b_val);
|
1214
|
+
} else if (FIXNUM_P (b)) {
|
1215
|
+
mpz_temp_alloc (b_val);
|
1216
|
+
mpz_init_set_si (b_val, FIX2NUM (b));
|
1201
1217
|
free_b_val = 1;
|
1202
|
-
} else if (BIGNUM_P(b)) {
|
1203
|
-
mpz_temp_from_bignum(b_val, b);
|
1218
|
+
} else if (BIGNUM_P (b)) {
|
1219
|
+
mpz_temp_from_bignum (b_val, b);
|
1204
1220
|
free_b_val = 1;
|
1205
1221
|
} else {
|
1206
|
-
typeerror_as(ZXB, "addend");
|
1222
|
+
typeerror_as (ZXB, "addend");
|
1207
1223
|
}
|
1208
|
-
mpz_get_struct(self, self_val);
|
1224
|
+
mpz_get_struct (self, self_val);
|
1209
1225
|
|
1210
1226
|
if (GMPZ_P (c)) {
|
1211
1227
|
mpz_get_struct (c, c_val);
|
@@ -1224,7 +1240,7 @@ static VALUE r_gmpz_submul_self(VALUE self, VALUE b, VALUE c)
|
|
1224
1240
|
} else {
|
1225
1241
|
if (free_b_val)
|
1226
1242
|
mpz_temp_free (b_val);
|
1227
|
-
|
1243
|
+
/* TODO?: rb_raise (rb_eTypeError, "base must be a Fixnum between 2 and 62, not a %s.", rb_class2name (rb_class_of (c)));*/
|
1228
1244
|
typeerror_as (ZXB, "multiplicand");
|
1229
1245
|
}
|
1230
1246
|
if (free_b_val)
|
@@ -1234,18 +1250,16 @@ static VALUE r_gmpz_submul_self(VALUE self, VALUE b, VALUE c)
|
|
1234
1250
|
|
1235
1251
|
/*
|
1236
1252
|
* Document-method: <<
|
1237
|
-
*
|
1238
1253
|
* call-seq:
|
1239
1254
|
* a << n
|
1240
1255
|
*
|
1241
|
-
* Returns _a_ times 2 raised to _n_. This operation can also be defined as a
|
1242
|
-
* by _n_ bits.
|
1256
|
+
* Returns _a_ times 2 raised to _n_. This operation can also be defined as a
|
1257
|
+
* left shift by _n_ bits.
|
1243
1258
|
*/
|
1244
1259
|
DEFUN_INT_F_UL(shl,mpz_mul_2exp,"shift size")
|
1245
1260
|
|
1246
1261
|
/*
|
1247
1262
|
* Document-method: neg
|
1248
|
-
*
|
1249
1263
|
* call-seq:
|
1250
1264
|
* a.neg
|
1251
1265
|
* -a
|
@@ -1254,7 +1268,6 @@ DEFUN_INT_F_UL(shl,mpz_mul_2exp,"shift size")
|
|
1254
1268
|
*/
|
1255
1269
|
/*
|
1256
1270
|
* Document-method: neg!
|
1257
|
-
*
|
1258
1271
|
* call-seq:
|
1259
1272
|
* a.neg!
|
1260
1273
|
*
|
@@ -1271,7 +1284,6 @@ DEFUN_INT2INT(neg, mpz_neg)
|
|
1271
1284
|
*/
|
1272
1285
|
/*
|
1273
1286
|
* Document-method: abs!
|
1274
|
-
*
|
1275
1287
|
* call-seq:
|
1276
1288
|
* a.abs!
|
1277
1289
|
*
|
@@ -1285,12 +1297,15 @@ DEFUN_INT2INT(abs, mpz_abs)
|
|
1285
1297
|
**********************************************************************/
|
1286
1298
|
|
1287
1299
|
/*
|
1300
|
+
* Document-method: /
|
1288
1301
|
* call-seq:
|
1289
1302
|
* a / b
|
1290
1303
|
*
|
1291
|
-
* Divides _a_ by _b_. Combines the different GMP division functions to provide
|
1292
|
-
* is hopefully looking for. The result will either be an instance of
|
1293
|
-
* depending on _b_. _b_ must be an instance of one of the
|
1304
|
+
* Divides _a_ by _b_. Combines the different GMP division functions to provide
|
1305
|
+
* what one is hopefully looking for. The result will either be an instance of
|
1306
|
+
* GMP::Q or GMP::F, depending on _b_. _b_ must be an instance of one of the
|
1307
|
+
* following:
|
1308
|
+
*
|
1294
1309
|
* * GMP::Z
|
1295
1310
|
* * Fixnum
|
1296
1311
|
* * GMP::Q
|
@@ -1308,12 +1323,12 @@ VALUE r_gmpz_div(VALUE self, VALUE arg)
|
|
1308
1323
|
MP_INT *self_val, *arg_val_z, *tmp_z;
|
1309
1324
|
MP_RAT *arg_val_q, *res_val_q;
|
1310
1325
|
MP_FLOAT *arg_val_f, *res_val_f;
|
1311
|
-
VALUE res;
|
1312
1326
|
#if defined(MPFR) && MPFR_VERSION_MAJOR>2
|
1313
1327
|
mpfr_prec_t prec;
|
1314
1328
|
#else
|
1315
1329
|
unsigned int prec;
|
1316
1330
|
#endif
|
1331
|
+
VALUE res = 0;
|
1317
1332
|
|
1318
1333
|
mpz_get_struct (self,self_val);
|
1319
1334
|
|
@@ -1363,45 +1378,44 @@ VALUE r_gmpz_div(VALUE self, VALUE arg)
|
|
1363
1378
|
|
1364
1379
|
/*
|
1365
1380
|
* Document-method: tdiv
|
1366
|
-
*
|
1367
1381
|
* call-seq:
|
1368
1382
|
* n.tdiv(d)
|
1369
1383
|
*
|
1370
|
-
* Divides _n_ by _d_, forming a quotient _q_. tdiv rounds _q_ towards zero.
|
1371
|
-
* stands for "truncate".
|
1384
|
+
* Divides _n_ by _d_, forming a quotient _q_. tdiv rounds _q_ towards zero.
|
1385
|
+
* The _t_ stands for "truncate".
|
1372
1386
|
*
|
1373
|
-
* _q_ will satisfy
|
1387
|
+
* _q_ will satisfy _n=q*d+r_, and _r_ will satisfy _0 <= abs(r ) < abs(d)_.
|
1374
1388
|
*
|
1375
1389
|
* This function calculates only the quotient.
|
1376
1390
|
*/
|
1377
1391
|
DEFUN_INT_DIV(tdiv, mpz_tdiv_q)
|
1392
|
+
|
1378
1393
|
/*
|
1379
1394
|
* Document-method: tmod
|
1380
|
-
*
|
1381
1395
|
* call-seq:
|
1382
1396
|
* n.tmod(d)
|
1383
1397
|
*
|
1384
|
-
* Divides _n_ by _d_, forming a remainder _r_. _r_ will have the same sign as
|
1385
|
-
* _t_ stands for "truncate".
|
1398
|
+
* Divides _n_ by _d_, forming a remainder _r_. _r_ will have the same sign as
|
1399
|
+
* _n_. The _t_ stands for "truncate".
|
1386
1400
|
*
|
1387
|
-
* _r_ will satisfy
|
1401
|
+
* _r_ will satisfy _n=q*d+r_, and _r_ will satisfy _0 <= abs(r ) < abs(d)_.
|
1388
1402
|
*
|
1389
1403
|
* This function calculates only the remainder.
|
1390
1404
|
*
|
1391
|
-
* The remainder can be negative, so the return value is the absolute value of
|
1392
|
-
* remainder.
|
1405
|
+
* The remainder can be negative, so the return value is the absolute value of
|
1406
|
+
* the remainder.
|
1393
1407
|
*/
|
1394
1408
|
DEFUN_INT_DIV(tmod, mpz_tdiv_r)
|
1409
|
+
|
1395
1410
|
/*
|
1396
1411
|
* Document-method: tshr
|
1397
|
-
*
|
1398
1412
|
* call-seq:
|
1399
1413
|
* n.tshr(d)
|
1400
1414
|
*
|
1401
|
-
* Divides _n_ by
|
1402
|
-
* _t_ stands for "truncate".
|
1415
|
+
* Divides _n_ by _2^d_, forming a quotient _q_. tshr rounds _q_ towards zero.
|
1416
|
+
* The _t_ stands for "truncate".
|
1403
1417
|
*
|
1404
|
-
* _q_ will satisfy
|
1418
|
+
* _q_ will satisfy _n=q*d+r_, and _r_ will satisfy _0 <= abs(r ) < abs(d)_.
|
1405
1419
|
*
|
1406
1420
|
* This function calculates only the quotient.
|
1407
1421
|
*/
|
@@ -1410,74 +1424,72 @@ DEFUN_INT_F_UL(tshrm,mpz_tdiv_r_2exp,"mark size")
|
|
1410
1424
|
|
1411
1425
|
/*
|
1412
1426
|
* Document-method: fdiv
|
1413
|
-
*
|
1414
1427
|
* call-seq:
|
1415
1428
|
* n.fdiv(d)
|
1416
1429
|
*
|
1417
|
-
* Divide _n_ by _d_, forming a quotient _q_. fdiv rounds _q_ down towards
|
1418
|
-
* The f stands for "floor".
|
1430
|
+
* Divide _n_ by _d_, forming a quotient _q_. fdiv rounds _q_ down towards
|
1431
|
+
* -infinity. The f stands for "floor".
|
1419
1432
|
*
|
1420
|
-
* _q_ will satisfy
|
1433
|
+
* _q_ will satisfy _n=q*d+r_.
|
1421
1434
|
*
|
1422
1435
|
* This function calculates only the quotient.
|
1423
1436
|
*/
|
1424
1437
|
DEFUN_INT_DIV(fdiv, mpz_fdiv_q)
|
1425
1438
|
/*
|
1426
1439
|
* Document-method: fmod
|
1427
|
-
*
|
1428
1440
|
* call-seq:
|
1429
1441
|
* n.fmod(d)
|
1430
1442
|
*
|
1431
|
-
* Divides _n_ by _d_, forming a remainder _r_. _r_ will have the same sign as
|
1432
|
-
* _f_ stands for "floor".
|
1443
|
+
* Divides _n_ by _d_, forming a remainder _r_. _r_ will have the same sign as
|
1444
|
+
* _d_. The _f_ stands for "floor".
|
1433
1445
|
*
|
1434
|
-
* _r_ will satisfy
|
1446
|
+
* _r_ will satisfy _n=q*d+r_, and _r_ will satisfy _0 <= abs(r ) < abs(d)_.
|
1435
1447
|
*
|
1436
1448
|
* This function calculates only the remainder.
|
1437
1449
|
*
|
1438
|
-
* The remainder can be negative, so the return value is the absolute value of
|
1439
|
-
* remainder.
|
1450
|
+
* The remainder can be negative, so the return value is the absolute value of
|
1451
|
+
* the remainder.
|
1440
1452
|
*/
|
1441
1453
|
DEFUN_INT_DIV(fmod, mpz_fdiv_r)
|
1442
|
-
DEFUN_INT_F_UL(fshr,mpz_fdiv_q_2exp,"shift size")
|
1443
|
-
DEFUN_INT_F_UL(fshrm,mpz_fdiv_r_2exp,"mark size")
|
1454
|
+
DEFUN_INT_F_UL(fshr, mpz_fdiv_q_2exp, "shift size")
|
1455
|
+
DEFUN_INT_F_UL(fshrm, mpz_fdiv_r_2exp, "mark size")
|
1444
1456
|
|
1445
1457
|
/*
|
1446
1458
|
* Document-method: cdiv
|
1447
|
-
*
|
1448
1459
|
* call-seq:
|
1449
1460
|
* n.cdiv(d)
|
1450
1461
|
*
|
1451
1462
|
* Divide _n_ by _d_, forming a quotient _q_. cdiv rounds _q_ up towards
|
1452
1463
|
* _+infinity_. The c stands for "ceil".
|
1453
1464
|
*
|
1454
|
-
* _q_ will satisfy
|
1465
|
+
* _q_ will satisfy _n=q*d+r_.
|
1455
1466
|
*
|
1456
1467
|
* This function calculates only the quotient.
|
1457
1468
|
*/
|
1458
1469
|
DEFUN_INT_DIV(cdiv, mpz_cdiv_q)
|
1459
1470
|
/*
|
1460
1471
|
* Document-method: cmod
|
1461
|
-
*
|
1462
1472
|
* call-seq:
|
1463
1473
|
* n.cmod(d)
|
1464
1474
|
*
|
1465
|
-
* Divides _n_ by _d_, forming a remainder _r_. _r_ will have the opposite sign
|
1466
|
-
* The c stands for "ceil".
|
1475
|
+
* Divides _n_ by _d_, forming a remainder _r_. _r_ will have the opposite sign
|
1476
|
+
* of _d_. The c stands for "ceil".
|
1467
1477
|
*
|
1468
|
-
* _r_ will satisfy
|
1478
|
+
* _r_ will satisfy _n=q*d+r_, and _r_ will satisfy _0 <= abs(r ) < abs(d)_.
|
1469
1479
|
*
|
1470
1480
|
* This function calculates only the remainder.
|
1471
1481
|
*/
|
1472
1482
|
DEFUN_INT_DIV(cmod, mpz_cdiv_r)
|
1473
1483
|
|
1474
1484
|
/*
|
1485
|
+
* Document-method: %
|
1475
1486
|
* call-seq:
|
1476
1487
|
* a % b
|
1477
1488
|
*
|
1478
1489
|
* @since 0.2.10
|
1479
1490
|
*
|
1480
1491
|
* Returns _a_ mod _b_. _b_ can be an instance any of the following:
|
1492
|
+
*
|
1481
1493
|
* * GMP::Z
|
1482
1494
|
* * Fixnum
|
1483
1495
|
* * Bignum
|
@@ -1485,34 +1497,37 @@ DEFUN_INT_DIV(cmod, mpz_cdiv_r)
|
|
1485
1497
|
VALUE r_gmpz_mod(VALUE self, VALUE arg)
|
1486
1498
|
{
|
1487
1499
|
MP_INT *self_val, *arg_val, *res_val;
|
1488
|
-
VALUE res;
|
1500
|
+
VALUE res = 0;
|
1489
1501
|
|
1490
|
-
mpz_get_struct(self,self_val);
|
1502
|
+
mpz_get_struct (self,self_val);
|
1491
1503
|
|
1492
|
-
if (GMPZ_P(arg)) {
|
1493
|
-
mpz_make_struct_init(res, res_val);
|
1494
|
-
mpz_get_struct(arg, arg_val);
|
1495
|
-
mpz_mod(res_val, self_val, arg_val);
|
1496
|
-
} else if (FIXNUM_P(arg)) {
|
1497
|
-
mpz_make_struct_init(res, res_val);
|
1498
|
-
mpz_mod_ui(res_val, self_val, FIX2NUM(arg));
|
1499
|
-
} else if (BIGNUM_P(arg)) {
|
1500
|
-
mpz_make_struct_init(res, res_val);
|
1501
|
-
mpz_set_bignum(res_val, arg);
|
1502
|
-
mpz_mod(res_val, res_val, self_val);
|
1504
|
+
if (GMPZ_P (arg)) {
|
1505
|
+
mpz_make_struct_init (res, res_val);
|
1506
|
+
mpz_get_struct (arg, arg_val);
|
1507
|
+
mpz_mod (res_val, self_val, arg_val);
|
1508
|
+
} else if (FIXNUM_P (arg)) {
|
1509
|
+
mpz_make_struct_init (res, res_val);
|
1510
|
+
mpz_mod_ui (res_val, self_val, FIX2NUM (arg));
|
1511
|
+
} else if (BIGNUM_P (arg)) {
|
1512
|
+
mpz_make_struct_init (res, res_val);
|
1513
|
+
mpz_set_bignum (res_val, arg);
|
1514
|
+
mpz_mod (res_val, res_val, self_val);
|
1503
1515
|
} else {
|
1504
|
-
typeerror(ZXB);
|
1516
|
+
typeerror (ZXB);
|
1505
1517
|
}
|
1506
1518
|
return res;
|
1507
1519
|
}
|
1508
1520
|
|
1509
1521
|
/*
|
1522
|
+
* Document-method: divisible?
|
1510
1523
|
* call-seq:
|
1511
1524
|
* a.divisible?(b)
|
1512
1525
|
*
|
1513
1526
|
* @since 0.5.23
|
1514
1527
|
*
|
1515
|
-
* Returns true if _a_ is divisible by _b_. _b_ can be an instance any of the
|
1528
|
+
* Returns true if _a_ is divisible by _b_. _b_ can be an instance any of the
|
1529
|
+
* following:
|
1530
|
+
*
|
1516
1531
|
* * GMP::Z
|
1517
1532
|
* * Fixnum
|
1518
1533
|
* * Bignum
|
@@ -1520,7 +1535,7 @@ VALUE r_gmpz_mod(VALUE self, VALUE arg)
|
|
1520
1535
|
static VALUE r_gmpz_divisible(VALUE self, VALUE arg)
|
1521
1536
|
{
|
1522
1537
|
MP_INT *self_val, *arg_val;
|
1523
|
-
int res;
|
1538
|
+
int res = 0;
|
1524
1539
|
mpz_get_struct (self, self_val);
|
1525
1540
|
|
1526
1541
|
if (FIXNUM_P (arg) && FIX2NUM (arg) > 0) {
|
@@ -1548,19 +1563,22 @@ static VALUE r_gmpz_divisible(VALUE self, VALUE arg)
|
|
1548
1563
|
}
|
1549
1564
|
|
1550
1565
|
/*
|
1566
|
+
* Document-method: congruent?
|
1551
1567
|
* call-seq:
|
1552
1568
|
* n.congruent?(c, d)
|
1553
1569
|
*
|
1554
1570
|
* @since 0.6.19
|
1555
1571
|
*
|
1556
|
-
* Returns true if _n_ is congruent to _c_ modulo _d_. _c_ and _d_ can be an
|
1572
|
+
* Returns true if _n_ is congruent to _c_ modulo _d_. _c_ and _d_ can be an
|
1573
|
+
* instance any of the following:
|
1574
|
+
*
|
1557
1575
|
* * GMP::Z
|
1558
1576
|
* * Fixnum
|
1559
1577
|
* * Bignum
|
1560
1578
|
*/
|
1561
1579
|
static VALUE r_gmpz_congruent(VALUE self_val, VALUE c_val, VALUE d_val)
|
1562
1580
|
{
|
1563
|
-
MP_INT *self, *c, *d;
|
1581
|
+
MP_INT *self, *c = NULL, *d = NULL;
|
1564
1582
|
int res, free_c, free_d;
|
1565
1583
|
mpz_get_struct (self_val, self);
|
1566
1584
|
free_c = free_d = 0;
|
@@ -1608,7 +1626,6 @@ static VALUE r_gmpz_congruent(VALUE self_val, VALUE c_val, VALUE d_val)
|
|
1608
1626
|
|
1609
1627
|
/*
|
1610
1628
|
* Document-method: **
|
1611
|
-
*
|
1612
1629
|
* call-seq:
|
1613
1630
|
* a ** b
|
1614
1631
|
*
|
@@ -1618,7 +1635,6 @@ DEFUN_INT_F_UL(pow,mpz_pow_ui,"exponent")
|
|
1618
1635
|
|
1619
1636
|
/*
|
1620
1637
|
* Document-method: GMP::Z.pow
|
1621
|
-
*
|
1622
1638
|
* call-seq:
|
1623
1639
|
* GMP::Z.pow(a, b)
|
1624
1640
|
*
|
@@ -1643,12 +1659,13 @@ VALUE r_gmpzsg_pow(VALUE klass, VALUE base, VALUE exp)
|
|
1643
1659
|
}
|
1644
1660
|
|
1645
1661
|
/*
|
1662
|
+
* Document-method: powmod
|
1646
1663
|
* call-seq:
|
1647
1664
|
* a.powmod(b, c)
|
1648
1665
|
*
|
1649
1666
|
* Returns _a_ raised to _b_ modulo _c_.
|
1650
1667
|
*
|
1651
|
-
* Negative _b_ is supported if an inverse
|
1668
|
+
* Negative _b_ is supported if an inverse _a^-1_ mod _c_ exists. If an inverse
|
1652
1669
|
* doesn't exist then a divide by zero is raised.
|
1653
1670
|
*/
|
1654
1671
|
VALUE r_gmpz_powm(VALUE self, VALUE exp, VALUE mod)
|
@@ -1717,28 +1734,27 @@ VALUE r_gmpz_powm(VALUE self, VALUE exp, VALUE mod)
|
|
1717
1734
|
|
1718
1735
|
/*
|
1719
1736
|
* Document-method: root
|
1720
|
-
*
|
1721
1737
|
* call-seq:
|
1722
1738
|
* a.root(b)
|
1723
1739
|
*
|
1724
|
-
* Returns the truncated integer part of the
|
1740
|
+
* Returns the truncated integer part of the _b_th root of _a_.
|
1725
1741
|
*/
|
1726
1742
|
DEFUN_INT_F_UL(root,mpz_root,"root number")
|
1727
1743
|
|
1728
1744
|
|
1729
1745
|
/*
|
1730
1746
|
* Document-method: rootrem
|
1731
|
-
*
|
1732
1747
|
* call-seq:
|
1733
1748
|
* a.rootrem(b)
|
1734
1749
|
*
|
1735
|
-
* Returns the truncated integer part of the
|
1750
|
+
* Returns the truncated integer part of the _b_th root of _a_, and the
|
1751
|
+
* remainder, _a - root**b_.
|
1736
1752
|
*/
|
1737
1753
|
static VALUE r_gmpz_rootrem(VALUE self_val, VALUE exp_val)
|
1738
1754
|
{
|
1739
1755
|
MP_INT *self, *root, *rem;
|
1740
1756
|
VALUE root_val, rem_val, ary;
|
1741
|
-
unsigned long exp;
|
1757
|
+
unsigned long exp = 0;
|
1742
1758
|
|
1743
1759
|
if (FIXNUM_P(exp_val)) {
|
1744
1760
|
if (FIX2NUM(exp_val) < 0)
|
@@ -1766,7 +1782,6 @@ static VALUE r_gmpz_rootrem(VALUE self_val, VALUE exp_val)
|
|
1766
1782
|
|
1767
1783
|
/*
|
1768
1784
|
* Document-method: sqrt
|
1769
|
-
*
|
1770
1785
|
* call-seq:
|
1771
1786
|
* a.sqrt
|
1772
1787
|
*
|
@@ -1774,7 +1789,6 @@ static VALUE r_gmpz_rootrem(VALUE self_val, VALUE exp_val)
|
|
1774
1789
|
*/
|
1775
1790
|
/*
|
1776
1791
|
* Document-method: sqrt!
|
1777
|
-
*
|
1778
1792
|
* call-seq:
|
1779
1793
|
* a.sqrt!
|
1780
1794
|
*
|
@@ -1783,11 +1797,12 @@ static VALUE r_gmpz_rootrem(VALUE self_val, VALUE exp_val)
|
|
1783
1797
|
DEFUN_INT2INT(sqrt, mpz_sqrt)
|
1784
1798
|
|
1785
1799
|
/*
|
1800
|
+
* Document-method: sqrtrem
|
1786
1801
|
* call-seq:
|
1787
1802
|
* a.sqrtrem #=> s, r
|
1788
1803
|
*
|
1789
|
-
* Returns the truncated integer part of the square root of _a_ as _s_ and the
|
1790
|
-
*
|
1804
|
+
* Returns the truncated integer part of the square root of _a_ as _s_ and the
|
1805
|
+
* remainder _a - s * s_ as _r_, which will be zero if _a_ is a perfect square.
|
1791
1806
|
*/
|
1792
1807
|
static VALUE r_gmpz_sqrtrem(VALUE self)
|
1793
1808
|
{
|
@@ -1803,25 +1818,25 @@ static VALUE r_gmpz_sqrtrem(VALUE self)
|
|
1803
1818
|
|
1804
1819
|
/*
|
1805
1820
|
* Document-method: power?
|
1806
|
-
*
|
1807
1821
|
* call-seq:
|
1808
1822
|
* p.power?
|
1809
1823
|
*
|
1810
|
-
* Returns true if _p_ is a perfect power, i.e., if there exist integers _a_
|
1811
|
-
* with
|
1824
|
+
* Returns true if _p_ is a perfect power, i.e., if there exist integers _a_
|
1825
|
+
* and _b_, with _b > 1_, such that _p_ equals _a_ raised to the power _b_.
|
1812
1826
|
*
|
1813
|
-
* Under this definition both 0 and 1 are considered to be perfect powers.
|
1814
|
-
* values of integers are accepted, but of course can only be odd
|
1827
|
+
* Under this definition both 0 and 1 are considered to be perfect powers.
|
1828
|
+
* Negative values of integers are accepted, but of course can only be odd
|
1829
|
+
* perfect powers.
|
1815
1830
|
*/
|
1816
1831
|
DEFUN_INT_COND_P(is_power,mpz_perfect_power_p)
|
1817
1832
|
/*
|
1818
1833
|
* Document-method: square?
|
1819
|
-
*
|
1820
1834
|
* call-seq:
|
1821
1835
|
* p.square?
|
1822
1836
|
*
|
1823
|
-
* Returns true if _p_ is a perfect square, i.e., if the square root of _p_ is
|
1824
|
-
* integer. Under this definition both 0 and 1 are considered to be perfect
|
1837
|
+
* Returns true if _p_ is a perfect square, i.e., if the square root of _p_ is
|
1838
|
+
* an integer. Under this definition both 0 and 1 are considered to be perfect
|
1839
|
+
* squares.
|
1825
1840
|
*/
|
1826
1841
|
DEFUN_INT_COND_P(is_square,mpz_perfect_square_p)
|
1827
1842
|
|
@@ -1831,27 +1846,28 @@ DEFUN_INT_COND_P(is_square,mpz_perfect_square_p)
|
|
1831
1846
|
**********************************************************************/
|
1832
1847
|
|
1833
1848
|
/*
|
1849
|
+
* Document-method: probab_prime?
|
1834
1850
|
* call-seq:
|
1835
1851
|
* n.probab_prime?(reps = 5)
|
1836
1852
|
*
|
1837
|
-
* Determine whether _n_ is prime. Returns 2 if _n_ is definitely prime,
|
1838
|
-
* is probably prime (without being certain), or returns 0 if
|
1839
|
-
* composite.
|
1853
|
+
* Determine whether _n_ is prime. Returns 2 if _n_ is definitely prime,
|
1854
|
+
* returns 1 if _n_ is probably prime (without being certain), or returns 0 if
|
1855
|
+
* _n_ is definitely composite.
|
1840
1856
|
*
|
1841
|
-
* This function does some trial divisions, then some Miller-Rabin
|
1842
|
-
* primality tests.
|
1843
|
-
* number, more will reduce the chances of a composite
|
1844
|
-
* prime".
|
1857
|
+
* This function does some trial divisions, then some Miller-Rabin
|
1858
|
+
* probabilistic primality tests. `reps` controls how many such tests are done,
|
1859
|
+
* 5 to 10 is a reasonable number, more will reduce the chances of a composite
|
1860
|
+
* being returned as "probably prime".
|
1845
1861
|
*
|
1846
|
-
* Miller-Rabin and similar tests can be more properly called compositeness
|
1847
|
-
* Numbers which fail are known to be composite but those which pass
|
1848
|
-
* might be composite. Only a few composites pass, hence
|
1849
|
-
* probably prime.
|
1862
|
+
* Miller-Rabin and similar tests can be more properly called compositeness
|
1863
|
+
* tests. Numbers which fail are known to be composite but those which pass
|
1864
|
+
* might be prime or might be composite. Only a few composites pass, hence
|
1865
|
+
* those which pass are considered probably prime.
|
1850
1866
|
*/
|
1851
1867
|
VALUE r_gmpz_is_probab_prime(int argc, VALUE* argv, VALUE self)
|
1852
1868
|
{
|
1853
1869
|
MP_INT *self_val;
|
1854
|
-
int reps_val;
|
1870
|
+
int reps_val = 0;
|
1855
1871
|
VALUE reps;
|
1856
1872
|
mpz_get_struct (self, self_val);
|
1857
1873
|
rb_scan_args (argc, argv, "01", &reps);
|
@@ -1868,43 +1884,44 @@ VALUE r_gmpz_is_probab_prime(int argc, VALUE* argv, VALUE self)
|
|
1868
1884
|
|
1869
1885
|
/*
|
1870
1886
|
* Document-method: nextprime
|
1871
|
-
*
|
1872
1887
|
* call-seq:
|
1873
1888
|
* n.nextprime
|
1874
1889
|
* n.next_prime
|
1875
1890
|
*
|
1876
1891
|
* Returns the next prime greater than _n_.
|
1877
1892
|
*
|
1878
|
-
* This function uses a probabilistic algorithm to identify primes. For
|
1879
|
-
* purposes it's adequate, the chance of a composite passing will be
|
1893
|
+
* This function uses a probabilistic algorithm to identify primes. For
|
1894
|
+
* practical purposes it's adequate, the chance of a composite passing will be
|
1895
|
+
* extremely small.
|
1880
1896
|
*/
|
1881
1897
|
/*
|
1882
1898
|
* Document-method: nextprime!
|
1883
|
-
*
|
1884
1899
|
* call-seq:
|
1885
1900
|
* n.nextprime!
|
1886
1901
|
* n.next_prime!
|
1887
1902
|
*
|
1888
1903
|
* Sets _n_ to the next prime greater than _n_.
|
1889
1904
|
*
|
1890
|
-
* This function uses a probabilistic algorithm to identify primes. For
|
1891
|
-
* purposes it's adequate, the chance of a composite passing will be
|
1905
|
+
* This function uses a probabilistic algorithm to identify primes. For
|
1906
|
+
* practical purposes it's adequate, the chance of a composite passing will be
|
1907
|
+
* extremely small.
|
1892
1908
|
*/
|
1893
1909
|
DEFUN_INT2INT(nextprime, mpz_nextprime)
|
1894
1910
|
|
1895
1911
|
/*
|
1912
|
+
* Document-method: gcd
|
1896
1913
|
* call-seq:
|
1897
1914
|
* a.gcd(b)
|
1898
1915
|
*
|
1899
1916
|
* @since 0.2.11
|
1900
1917
|
*
|
1901
|
-
* Returns the greatest common divisor of
|
1902
|
-
* one or both of _a_ or _b_ are negative.
|
1918
|
+
* Returns the greatest common divisor of _a_ and _b_. The result is always
|
1919
|
+
* positive even if one or both of _a_ or _b_ are negative.
|
1903
1920
|
*/
|
1904
1921
|
VALUE r_gmpz_gcd(VALUE self, VALUE arg)
|
1905
1922
|
{
|
1906
1923
|
MP_INT *self_val, *arg_val, *res_val;
|
1907
|
-
VALUE res;
|
1924
|
+
VALUE res = 0;
|
1908
1925
|
|
1909
1926
|
mpz_get_struct (self,self_val);
|
1910
1927
|
|
@@ -1926,20 +1943,21 @@ VALUE r_gmpz_gcd(VALUE self, VALUE arg)
|
|
1926
1943
|
}
|
1927
1944
|
|
1928
1945
|
/*
|
1946
|
+
* Document-method: gcdext
|
1929
1947
|
* call-seq:
|
1930
1948
|
* a.gcdext(b) #=> g, s, t
|
1931
1949
|
*
|
1932
1950
|
* @since 0.5.23
|
1933
1951
|
*
|
1934
|
-
* Returns the greatest common divisor of _a_ and _b_, in addition to _s_ and
|
1935
|
-
* coefficients satisfying
|
1936
|
-
* both of _a_ and _b_ are negative. _s_ and _t_ are chosen such
|
1937
|
-
*
|
1952
|
+
* Returns the greatest common divisor of _a_ and _b_, in addition to _s_ and
|
1953
|
+
* _t_, the coefficients satisfying _a*s + b*t = g_. _g_ is always positive,
|
1954
|
+
* even if one or both of _a_ and _b_ are negative. _s_ and _t_ are chosen such
|
1955
|
+
* that _abs(s) <= abs(b)_ and _abs(t) <= abs(a)_.
|
1938
1956
|
*/
|
1939
1957
|
VALUE r_gmpz_gcdext(VALUE self, VALUE arg)
|
1940
1958
|
{
|
1941
1959
|
MP_INT *self_val, *arg_val, *res_val, *s_val, *t_val;
|
1942
|
-
VALUE res, s, t, ary;
|
1960
|
+
VALUE res = 0, s = 0, t = 0, ary;
|
1943
1961
|
int free_arg_val = 0;
|
1944
1962
|
|
1945
1963
|
mpz_get_struct (self,self_val);
|
@@ -1976,20 +1994,21 @@ VALUE r_gmpz_gcdext(VALUE self, VALUE arg)
|
|
1976
1994
|
}
|
1977
1995
|
|
1978
1996
|
/*
|
1997
|
+
* Document-method: gcdext2
|
1979
1998
|
* call-seq:
|
1980
1999
|
* a.gcdext2(b) #=> g, s
|
1981
2000
|
*
|
1982
2001
|
* @since 0.5.x
|
1983
2002
|
*
|
1984
2003
|
* Returns the greatest common divisor of _a_ and _b_, in addition to _s_, the
|
1985
|
-
* coefficient satisfying
|
1986
|
-
* both of _a_ and _b_ are negative. _s_ and _t_ are chosen such that
|
1987
|
-
*
|
2004
|
+
* coefficient satisfying _a*s + b*t = g_. _g_ is always positive, even if one
|
2005
|
+
* or both of _a_ and _b_ are negative. _s_ and _t_ are chosen such that
|
2006
|
+
* _abs(s) <= abs(b)_ and _abs(t) <= abs(a)_.
|
1988
2007
|
*/
|
1989
2008
|
VALUE r_gmpz_gcdext2(VALUE self, VALUE arg)
|
1990
2009
|
{
|
1991
2010
|
MP_INT *self_val, *arg_val, *res_val, *s_val;
|
1992
|
-
VALUE res, s, ary;
|
2011
|
+
VALUE res = 0, s = 0, ary;
|
1993
2012
|
int free_arg_val = 0;
|
1994
2013
|
|
1995
2014
|
mpz_get_struct (self,self_val);
|
@@ -2023,18 +2042,19 @@ VALUE r_gmpz_gcdext2(VALUE self, VALUE arg)
|
|
2023
2042
|
}
|
2024
2043
|
|
2025
2044
|
/*
|
2045
|
+
* Document-method: lcm
|
2026
2046
|
* call-seq:
|
2027
2047
|
* a.lcm(b)
|
2028
2048
|
*
|
2029
2049
|
* @since 0.2.11
|
2030
2050
|
*
|
2031
|
-
* Returns the least common multiple of
|
2032
|
-
* one or both of _a_ or _b_ are negative.
|
2051
|
+
* Returns the least common multiple of _a_ and _b_. The result is always
|
2052
|
+
* positive even if one or both of _a_ or _b_ are negative.
|
2033
2053
|
*/
|
2034
2054
|
VALUE r_gmpz_lcm(VALUE self, VALUE arg)
|
2035
2055
|
{
|
2036
2056
|
MP_INT *self_val, *arg_val, *res_val;
|
2037
|
-
VALUE res;
|
2057
|
+
VALUE res = 0;
|
2038
2058
|
|
2039
2059
|
mpz_get_struct (self,self_val);
|
2040
2060
|
|
@@ -2056,19 +2076,20 @@ VALUE r_gmpz_lcm(VALUE self, VALUE arg)
|
|
2056
2076
|
}
|
2057
2077
|
|
2058
2078
|
/*
|
2079
|
+
* Document-method: invert
|
2059
2080
|
* call-seq:
|
2060
2081
|
* a.invert(b)
|
2061
2082
|
*
|
2062
2083
|
* @since 0.2.11
|
2063
2084
|
*
|
2064
|
-
* Returns the inverse of _a_ modulo _b_. If the inverse exists, the return
|
2065
|
-
* non-zero and the result will be non-negative and less than _b_. If
|
2066
|
-
* exist, the result is undefined.
|
2085
|
+
* Returns the inverse of _a_ modulo _b_. If the inverse exists, the return
|
2086
|
+
* value is non-zero and the result will be non-negative and less than _b_. If
|
2087
|
+
* an inverse doesn't exist, the result is undefined.
|
2067
2088
|
*/
|
2068
2089
|
VALUE r_gmpz_invert(VALUE self, VALUE arg)
|
2069
2090
|
{
|
2070
2091
|
MP_INT *self_val, *arg_val, *res_val;
|
2071
|
-
VALUE res;
|
2092
|
+
VALUE res = 0;
|
2072
2093
|
|
2073
2094
|
mpz_get_struct (self,self_val);
|
2074
2095
|
|
@@ -2092,10 +2113,11 @@ VALUE r_gmpz_invert(VALUE self, VALUE arg)
|
|
2092
2113
|
}
|
2093
2114
|
|
2094
2115
|
/*
|
2116
|
+
* Document-method: jacobi
|
2095
2117
|
* call-seq:
|
2096
2118
|
* a.jacobi(b)
|
2097
2119
|
*
|
2098
|
-
* Calculate the Jacobi symbol
|
2120
|
+
* Calculate the Jacobi symbol _(a/b)_. This is defined only for _b_ odd and
|
2099
2121
|
* positive.
|
2100
2122
|
*/
|
2101
2123
|
VALUE r_gmpz_jacobi(VALUE self, VALUE b)
|
@@ -2113,15 +2135,16 @@ VALUE r_gmpz_jacobi(VALUE self, VALUE b)
|
|
2113
2135
|
}
|
2114
2136
|
|
2115
2137
|
/*
|
2138
|
+
* Document-method: jacobi
|
2116
2139
|
* call-seq:
|
2117
2140
|
* GMP::Z.jacobi(a, b)
|
2118
2141
|
*
|
2119
|
-
* Calculate the Jacobi symbol
|
2142
|
+
* Calculate the Jacobi symbol _(a/b)_. This is defined only for _b_ odd and
|
2120
2143
|
* positive.
|
2121
2144
|
*/
|
2122
2145
|
VALUE r_gmpzsg_jacobi(VALUE klass, VALUE a, VALUE b)
|
2123
2146
|
{
|
2124
|
-
MP_INT *a_val, *b_val;
|
2147
|
+
MP_INT *a_val = NULL, *b_val = NULL;
|
2125
2148
|
int res_val;
|
2126
2149
|
int free_a_val = 0;
|
2127
2150
|
int free_b_val = 0;
|
@@ -2176,10 +2199,11 @@ VALUE r_gmpzsg_jacobi(VALUE klass, VALUE a, VALUE b)
|
|
2176
2199
|
}
|
2177
2200
|
|
2178
2201
|
/*
|
2202
|
+
* Document-method: legendre
|
2179
2203
|
* call-seq:
|
2180
2204
|
* a.legendre(p)
|
2181
2205
|
*
|
2182
|
-
* Calculate the Legendre symbol
|
2206
|
+
* Calculate the Legendre symbol _(a/p)_. This is defined only for _p_ an odd
|
2183
2207
|
* positive prime, and for such _p_ it's identical to the Jacobi symbol.
|
2184
2208
|
*/
|
2185
2209
|
VALUE r_gmpz_legendre(VALUE self, VALUE p)
|
@@ -2199,11 +2223,12 @@ VALUE r_gmpz_legendre(VALUE self, VALUE p)
|
|
2199
2223
|
}
|
2200
2224
|
|
2201
2225
|
/*
|
2226
|
+
* Document-method: remove
|
2202
2227
|
* call-seq:
|
2203
2228
|
* n.remove(f) #=> r, t
|
2204
2229
|
*
|
2205
|
-
* Remove all occurrences of the factor _f_ from _n_, returning the result as
|
2206
|
-
*
|
2230
|
+
* Remove all occurrences of the factor _f_ from _n_, returning the result as
|
2231
|
+
* _r_. _t_, the number of occurrences that were removed, is also returned.
|
2207
2232
|
*/
|
2208
2233
|
VALUE r_gmpz_remove(VALUE self, VALUE arg)
|
2209
2234
|
{
|
@@ -2212,165 +2237,161 @@ VALUE r_gmpz_remove(VALUE self, VALUE arg)
|
|
2212
2237
|
#if __GNU_MP_VERSION>2
|
2213
2238
|
unsigned long removed_val;
|
2214
2239
|
#else
|
2215
|
-
int
|
2240
|
+
int removed_val;
|
2216
2241
|
#endif
|
2217
2242
|
int free_arg_val = 0;
|
2243
|
+
arg_val = NULL;
|
2218
2244
|
|
2219
|
-
mpz_get_struct(self, self_val);
|
2245
|
+
mpz_get_struct (self, self_val);
|
2220
2246
|
|
2221
|
-
if (GMPZ_P(arg)) {
|
2222
|
-
mpz_get_struct(arg,arg_val);
|
2223
|
-
if (mpz_sgn(arg_val) != 1)
|
2224
|
-
rb_raise(rb_eRangeError, "argument must be positive");
|
2225
|
-
} else if (FIXNUM_P(arg)) {
|
2226
|
-
if (FIX2NUM(arg) <= 0)
|
2227
|
-
rb_raise(rb_eRangeError, "argument must be positive");
|
2228
|
-
mpz_temp_alloc(arg_val);
|
2229
|
-
mpz_init_set_ui(arg_val, FIX2NUM(arg));
|
2230
|
-
} else if (BIGNUM_P(arg)) {
|
2231
|
-
mpz_temp_from_bignum(arg_val, arg);
|
2232
|
-
if (mpz_sgn(arg_val) != 1) {
|
2233
|
-
mpz_temp_free(arg_val);
|
2234
|
-
rb_raise(rb_eRangeError, "argument must be positive");
|
2247
|
+
if (GMPZ_P (arg)) {
|
2248
|
+
mpz_get_struct (arg,arg_val);
|
2249
|
+
if (mpz_sgn (arg_val) != 1)
|
2250
|
+
rb_raise (rb_eRangeError, "argument must be positive");
|
2251
|
+
} else if (FIXNUM_P (arg)) {
|
2252
|
+
if (FIX2NUM (arg) <= 0)
|
2253
|
+
rb_raise (rb_eRangeError, "argument must be positive");
|
2254
|
+
mpz_temp_alloc (arg_val);
|
2255
|
+
mpz_init_set_ui (arg_val, FIX2NUM (arg));
|
2256
|
+
} else if (BIGNUM_P (arg)) {
|
2257
|
+
mpz_temp_from_bignum (arg_val, arg);
|
2258
|
+
if (mpz_sgn (arg_val) != 1) {
|
2259
|
+
mpz_temp_free (arg_val);
|
2260
|
+
rb_raise (rb_eRangeError, "argument must be positive");
|
2235
2261
|
}
|
2236
2262
|
} else {
|
2237
|
-
typeerror(ZXB);
|
2263
|
+
typeerror (ZXB);
|
2238
2264
|
}
|
2239
2265
|
|
2240
|
-
mpz_make_struct_init(res, res_val);
|
2241
|
-
removed_val = mpz_remove(res_val, self_val, arg_val);
|
2266
|
+
mpz_make_struct_init (res, res_val);
|
2267
|
+
removed_val = mpz_remove (res_val, self_val, arg_val);
|
2242
2268
|
|
2243
2269
|
if (free_arg_val)
|
2244
|
-
mpz_temp_free(arg_val);
|
2270
|
+
mpz_temp_free (arg_val);
|
2245
2271
|
|
2246
|
-
return rb_assoc_new(res, INT2FIX(removed_val));
|
2272
|
+
return rb_assoc_new (res, INT2FIX (removed_val));
|
2247
2273
|
}
|
2248
2274
|
|
2249
2275
|
/*
|
2250
|
-
* Document-method:
|
2251
|
-
*
|
2276
|
+
* Document-method: fac
|
2252
2277
|
* call-seq:
|
2253
2278
|
* GMP::Z.fac(n)
|
2254
2279
|
*
|
2255
|
-
* Returns
|
2280
|
+
* Returns _n!_, the factorial of _n_.
|
2256
2281
|
*
|
2257
|
-
*
|
2258
|
-
*
|
2259
|
-
*
|
2260
|
-
*
|
2261
|
-
*
|
2262
|
-
*
|
2282
|
+
* @example
|
2283
|
+
* GMP::Z.fac(0) #=> 1
|
2284
|
+
* GMP::Z.fac(1) #=> 1
|
2285
|
+
* GMP::Z.fac(2) #=> 2
|
2286
|
+
* GMP::Z.fac(3) #=> 6
|
2287
|
+
* GMP::Z.fac(4) #=> 24
|
2263
2288
|
*/
|
2264
2289
|
DEFUN_INT_SINGLETON_UI(fac, mpz_fac_ui)
|
2265
2290
|
#if __GNU_MP_VERSION >= 5 && __GNU_MP_VERSION_MINOR >= 1 // 5.1.0 and newer
|
2266
2291
|
|
2267
2292
|
/*
|
2268
|
-
* Document-method:
|
2269
|
-
*
|
2293
|
+
* Document-method: double_fac
|
2270
2294
|
* call-seq:
|
2271
|
-
* GMP::Z.send(:"2fac", n)
|
2272
2295
|
* GMP::Z.double_fac(n)
|
2296
|
+
* GMP::Z.send(:"2fac", n)
|
2273
2297
|
*
|
2274
|
-
* Returns
|
2275
|
-
*
|
2276
|
-
*
|
2277
|
-
*
|
2278
|
-
*
|
2279
|
-
*
|
2280
|
-
*
|
2281
|
-
*
|
2282
|
-
*
|
2283
|
-
*
|
2284
|
-
*
|
2285
|
-
*
|
2286
|
-
*
|
2287
|
-
*
|
2288
|
-
*
|
2289
|
-
* #=> 34243224702511976248246432895208185975118675053719198827915654463488000000000000
|
2298
|
+
* Returns _n!!_, the double factorial of _n_.
|
2299
|
+
*
|
2300
|
+
* @example
|
2301
|
+
* GMP::Z.double_fac( 0) #=> 1
|
2302
|
+
* GMP::Z.double_fac( 1) #=> 1
|
2303
|
+
* GMP::Z.double_fac( 2) #=> 2
|
2304
|
+
* GMP::Z.double_fac( 3) #=> 3
|
2305
|
+
* GMP::Z.double_fac( 4) #=> 8
|
2306
|
+
* GMP::Z.double_fac( 5) #=> 15
|
2307
|
+
* GMP::Z.double_fac( 6) #=> 48
|
2308
|
+
* GMP::Z.double_fac( 7) #=> 105
|
2309
|
+
* GMP::Z.double_fac( 8) #=> 384
|
2310
|
+
* GMP::Z.double_fac( 9) #=> 945
|
2311
|
+
* GMP::Z.double_fac( 10) #=> 3840
|
2312
|
+
* GMP::Z.double_fac(100) #=> 34243224702511976248246432895208185975118675053719198827915654463488000000000000
|
2290
2313
|
*/
|
2291
2314
|
DEFUN_INT_SINGLETON_UI(2fac, mpz_2fac_ui)
|
2292
2315
|
|
2293
2316
|
/*
|
2294
|
-
* Document-method:
|
2295
|
-
*
|
2317
|
+
* Document-method: mfac
|
2296
2318
|
* call-seq:
|
2297
2319
|
* GMP::Z.mfac(n, m)
|
2298
2320
|
*
|
2299
|
-
* Returns
|
2300
|
-
*
|
2301
|
-
*
|
2302
|
-
*
|
2303
|
-
*
|
2304
|
-
*
|
2305
|
-
*
|
2306
|
-
*
|
2307
|
-
*
|
2308
|
-
*
|
2309
|
-
*
|
2310
|
-
*
|
2311
|
-
*
|
2312
|
-
*
|
2313
|
-
*
|
2314
|
-
*
|
2321
|
+
* Returns _n!^(m)_, the m-multi-factorial of _n_.
|
2322
|
+
*
|
2323
|
+
* @example
|
2324
|
+
* GMP::Z.mfac(0, 3) #=> 1
|
2325
|
+
* GMP::Z.mfac(1, 3) #=> 1
|
2326
|
+
* GMP::Z.mfac(2, 3) #=> 2
|
2327
|
+
* GMP::Z.mfac(3, 3) #=> 3
|
2328
|
+
* GMP::Z.mfac(4, 3) #=> 4
|
2329
|
+
* GMP::Z.mfac(5, 3) #=> 10
|
2330
|
+
* GMP::Z.mfac(6, 3) #=> 18
|
2331
|
+
* GMP::Z.mfac(7, 3) #=> 28
|
2332
|
+
* GMP::Z.mfac(8, 3) #=> 80
|
2333
|
+
* GMP::Z.mfac(9, 3) #=> 162
|
2334
|
+
* GMP::Z.mfac(10, 3) #=> 280
|
2335
|
+
* GMP::Z.mfac(11, 3) #=> 880
|
2336
|
+
* GMP::Z.mfac(12, 3) #=> 1944
|
2315
2337
|
*/
|
2316
2338
|
DEFUN_INT_SINGLETON_UIUI(mfac, mpz_mfac_uiui)
|
2317
2339
|
|
2318
2340
|
/*
|
2319
|
-
* Document-method:
|
2320
|
-
*
|
2341
|
+
* Document-method: primorial
|
2321
2342
|
* call-seq:
|
2322
2343
|
* GMP::Z.primorial(n)
|
2323
2344
|
*
|
2324
2345
|
* Returns the primorial of _n_.
|
2325
2346
|
*
|
2326
|
-
*
|
2327
|
-
*
|
2328
|
-
*
|
2329
|
-
*
|
2330
|
-
*
|
2331
|
-
*
|
2332
|
-
*
|
2333
|
-
*
|
2334
|
-
*
|
2347
|
+
* @example
|
2348
|
+
* GMP::Z.primorial(0) #=> 1
|
2349
|
+
* GMP::Z.primorial(1) #=> 1
|
2350
|
+
* GMP::Z.primorial(2) #=> 2
|
2351
|
+
* GMP::Z.primorial(3) #=> 6
|
2352
|
+
* GMP::Z.primorial(4) #=> 6
|
2353
|
+
* GMP::Z.primorial(5) #=> 30
|
2354
|
+
* GMP::Z.primorial(6) #=> 30
|
2355
|
+
* GMP::Z.primorial(7) #=> 210
|
2335
2356
|
*/
|
2336
2357
|
DEFUN_INT_SINGLETON_UI(primorial, mpz_primorial_ui)
|
2337
2358
|
#endif
|
2338
2359
|
|
2339
2360
|
/*
|
2340
|
-
* Document-method:
|
2341
|
-
*
|
2361
|
+
* Document-method: fib
|
2342
2362
|
* call-seq:
|
2343
2363
|
* GMP::Z.fib(n)
|
2344
2364
|
*
|
2345
|
-
* Returns
|
2365
|
+
* Returns _F [n]_, the _nth_ Fibonacci number.
|
2346
2366
|
*
|
2347
|
-
*
|
2348
|
-
*
|
2349
|
-
*
|
2350
|
-
*
|
2351
|
-
*
|
2352
|
-
*
|
2353
|
-
*
|
2354
|
-
*
|
2367
|
+
* @example
|
2368
|
+
* GMP::Z.fib(1) #=> 1
|
2369
|
+
* GMP::Z.fib(2) #=> 1
|
2370
|
+
* GMP::Z.fib(3) #=> 2
|
2371
|
+
* GMP::Z.fib(4) #=> 3
|
2372
|
+
* GMP::Z.fib(5) #=> 5
|
2373
|
+
* GMP::Z.fib(6) #=> 8
|
2374
|
+
* GMP::Z.fib(7) #=> 13
|
2355
2375
|
*/
|
2356
2376
|
DEFUN_INT_SINGLETON_UI(fib, mpz_fib_ui)
|
2357
2377
|
|
2358
2378
|
/*
|
2359
|
-
* Document-method:
|
2360
|
-
*
|
2379
|
+
* Document-method: fib2
|
2361
2380
|
* call-seq:
|
2362
2381
|
* GMP::Z.fib2(n)
|
2363
2382
|
*
|
2364
|
-
* Returns [
|
2383
|
+
* Returns [_F [n]_, _F [n-1]_], the _nth_ and _n-1th_ Fibonacci numbers.
|
2384
|
+
*
|
2385
|
+
* @since 0.6.41
|
2365
2386
|
*
|
2366
|
-
*
|
2367
|
-
*
|
2368
|
-
*
|
2369
|
-
*
|
2370
|
-
*
|
2371
|
-
*
|
2372
|
-
*
|
2373
|
-
*
|
2387
|
+
* @example
|
2388
|
+
* GMP::Z.fib2(1) #=> [ 1, 0]
|
2389
|
+
* GMP::Z.fib2(2) #=> [ 1, 1]
|
2390
|
+
* GMP::Z.fib2(3) #=> [ 2, 1]
|
2391
|
+
* GMP::Z.fib2(4) #=> [ 3, 2]
|
2392
|
+
* GMP::Z.fib2(5) #=> [ 5, 3]
|
2393
|
+
* GMP::Z.fib2(6) #=> [ 8, 5]
|
2394
|
+
* GMP::Z.fib2(7) #=> [13, 8]
|
2374
2395
|
*/
|
2375
2396
|
DEFUN_INT_SINGLETON_ZZ_UI(fib2, mpz_fib2_ui)
|
2376
2397
|
|
@@ -2382,6 +2403,7 @@ DEFUN_INT_SINGLETON_UI(lucnum, mpz_lucnum_ui)
|
|
2382
2403
|
**********************************************************************/
|
2383
2404
|
|
2384
2405
|
/*
|
2406
|
+
* Document-method: ==
|
2385
2407
|
* call-seq:
|
2386
2408
|
* a == b
|
2387
2409
|
*
|
@@ -2446,9 +2468,12 @@ int mpz_cmp_value(MP_INT *OP, VALUE arg)
|
|
2446
2468
|
} else {
|
2447
2469
|
typeerror_as(ZQFXB, "exponent");
|
2448
2470
|
}
|
2471
|
+
|
2472
|
+
return 0; /* should never get here */
|
2449
2473
|
}
|
2450
2474
|
|
2451
2475
|
/*
|
2476
|
+
* Document-method: <=>
|
2452
2477
|
* call-seq:
|
2453
2478
|
* a <=> b
|
2454
2479
|
*
|
@@ -2474,34 +2499,33 @@ VALUE r_gmpz_cmp(VALUE self, VALUE arg)
|
|
2474
2499
|
|
2475
2500
|
/*
|
2476
2501
|
* Document-method: <
|
2477
|
-
*
|
2478
2502
|
* call-seq:
|
2479
2503
|
* a < b
|
2480
2504
|
*
|
2481
2505
|
* Returns whether _a_ is strictly less than _b_.
|
2482
2506
|
*/
|
2483
2507
|
DEFUN_INT_CMP(lt,<)
|
2508
|
+
|
2484
2509
|
/*
|
2485
2510
|
* Document-method: <=
|
2486
|
-
*
|
2487
2511
|
* call-seq:
|
2488
2512
|
* a <= b
|
2489
2513
|
*
|
2490
2514
|
* Returns whether _a_ is less than or equal to _b_.
|
2491
2515
|
*/
|
2492
2516
|
DEFUN_INT_CMP(le,<=)
|
2517
|
+
|
2493
2518
|
/*
|
2494
2519
|
* Document-method: >
|
2495
|
-
*
|
2496
2520
|
* call-seq:
|
2497
2521
|
* a > b
|
2498
2522
|
*
|
2499
2523
|
* Returns whether _a_ is strictly greater than _b_.
|
2500
2524
|
*/
|
2501
2525
|
DEFUN_INT_CMP(gt,>)
|
2526
|
+
|
2502
2527
|
/*
|
2503
2528
|
* Document-method: >=
|
2504
|
-
*
|
2505
2529
|
* call-seq:
|
2506
2530
|
* a >= b
|
2507
2531
|
*
|
@@ -2510,14 +2534,15 @@ DEFUN_INT_CMP(gt,>)
|
|
2510
2534
|
DEFUN_INT_CMP(ge,>=)
|
2511
2535
|
|
2512
2536
|
/*
|
2537
|
+
* Document-method: cmpabs
|
2513
2538
|
* call-seq:
|
2514
2539
|
* a.cmpabs(b)
|
2515
2540
|
*
|
2516
|
-
* Returns negative if
|
2541
|
+
* Returns negative if _abs(a)_ is less than _abs(b)_.
|
2517
2542
|
*
|
2518
|
-
* Returns 0 if
|
2543
|
+
* Returns 0 if _abs(a)_ is equal to _abs(b)_.
|
2519
2544
|
*
|
2520
|
-
* Returns positive if
|
2545
|
+
* Returns positive if _abs(a)_ is greater than _abs(b)_.
|
2521
2546
|
*/
|
2522
2547
|
VALUE r_gmpz_cmpabs(VALUE self, VALUE arg)
|
2523
2548
|
{
|
@@ -2553,9 +2578,12 @@ VALUE r_gmpz_cmpabs(VALUE self, VALUE arg)
|
|
2553
2578
|
} else {
|
2554
2579
|
typeerror(ZQFXB);
|
2555
2580
|
}
|
2581
|
+
|
2582
|
+
return Qnil; /* should never get here */
|
2556
2583
|
}
|
2557
2584
|
|
2558
2585
|
/*
|
2586
|
+
* Document-method: sgn
|
2559
2587
|
* call-seq:
|
2560
2588
|
* a.sgn
|
2561
2589
|
*
|
@@ -2569,14 +2597,15 @@ VALUE r_gmpz_sgn(VALUE self)
|
|
2569
2597
|
}
|
2570
2598
|
|
2571
2599
|
/*
|
2600
|
+
* Document-method: eql?
|
2572
2601
|
* call-seq:
|
2573
2602
|
* a.eql?(b)
|
2574
2603
|
*
|
2575
2604
|
* @since 0.4.7
|
2576
2605
|
*
|
2577
|
-
* Returns true if _a_ is equal to _b_. _a_ and _b_ must then be equal in
|
2578
|
-
* and both be instances of GMP::Z. Otherwise, returns false.
|
2579
|
-
* b.class == GMP::Z
|
2606
|
+
* Returns true if _a_ is equal to _b_. _a_ and _b_ must then be equal in
|
2607
|
+
* cardinality, and both be instances of GMP::Z. Otherwise, returns false.
|
2608
|
+
* `a.eql?(b)` if and only if `b.class == GMP::Z`, and `a.hash == b.hash`.
|
2580
2609
|
*/
|
2581
2610
|
VALUE r_gmpz_eql(VALUE self, VALUE arg)
|
2582
2611
|
{
|
@@ -2593,14 +2622,16 @@ VALUE r_gmpz_eql(VALUE self, VALUE arg)
|
|
2593
2622
|
}
|
2594
2623
|
|
2595
2624
|
/*
|
2625
|
+
* Document-method: hash
|
2596
2626
|
* call-seq:
|
2597
2627
|
* a.hash
|
2598
2628
|
*
|
2599
2629
|
* @since 0.4.7
|
2600
2630
|
*
|
2601
|
-
* Returns the computed hash value of _a_. This method first converts _a_ into
|
2602
|
-
* (base 10), then calls String#hash on the result, returning the hash
|
2603
|
-
* if and only if b.class == GMP::Z
|
2631
|
+
* Returns the computed hash value of _a_. This method first converts _a_ into
|
2632
|
+
* a String (base 10), then calls String#hash on the result, returning the hash
|
2633
|
+
* value. `a.eql?(b)` if and only if `b.class == GMP::Z`, and
|
2634
|
+
* `a.hash == b.hash`.
|
2604
2635
|
*/
|
2605
2636
|
VALUE r_gmpz_hash(VALUE self)
|
2606
2637
|
{
|
@@ -2616,11 +2647,12 @@ VALUE r_gmpz_hash(VALUE self)
|
|
2616
2647
|
|
2617
2648
|
/*
|
2618
2649
|
* Document-method: &
|
2619
|
-
*
|
2620
2650
|
* call-seq:
|
2621
2651
|
* a & b
|
2622
2652
|
*
|
2623
|
-
* Returns _a_ bitwise-and _b_. _b_ must be an instance of one of the
|
2653
|
+
* Returns _a_ bitwise-and _b_. _b_ must be an instance of one of the
|
2654
|
+
* following:
|
2655
|
+
*
|
2624
2656
|
* * GMP::Z
|
2625
2657
|
* * Fixnum
|
2626
2658
|
* * Bignum
|
@@ -2628,11 +2660,12 @@ VALUE r_gmpz_hash(VALUE self)
|
|
2628
2660
|
DEFUN_INT_LOGIC(and, mpz_and)
|
2629
2661
|
/*
|
2630
2662
|
* Document-method: |
|
2631
|
-
*
|
2632
2663
|
* call-seq:
|
2633
2664
|
* a | b
|
2634
2665
|
*
|
2635
|
-
* Returns _a_ bitwise inclusive-or _b_. _b_ must be an instance of one of the
|
2666
|
+
* Returns _a_ bitwise inclusive-or _b_. _b_ must be an instance of one of the
|
2667
|
+
* following:
|
2668
|
+
*
|
2636
2669
|
* * GMP::Z
|
2637
2670
|
* * Fixnum
|
2638
2671
|
* * Bignum
|
@@ -2640,11 +2673,12 @@ DEFUN_INT_LOGIC(and, mpz_and)
|
|
2640
2673
|
DEFUN_INT_LOGIC(or, mpz_ior)
|
2641
2674
|
/*
|
2642
2675
|
* Document-method: ^
|
2643
|
-
*
|
2644
2676
|
* call-seq:
|
2645
2677
|
* a ^ b
|
2646
2678
|
*
|
2647
|
-
* Returns _a_ bitwise exclusive-or _b_. _b_ must be an instance of one of the
|
2679
|
+
* Returns _a_ bitwise exclusive-or _b_. _b_ must be an instance of one of the
|
2680
|
+
* following:
|
2681
|
+
*
|
2648
2682
|
* * GMP::Z
|
2649
2683
|
* * Fixnum
|
2650
2684
|
* * Bignum
|
@@ -2653,7 +2687,6 @@ DEFUN_INT_LOGIC(xor, mpz_xor)
|
|
2653
2687
|
|
2654
2688
|
/*
|
2655
2689
|
* Document-method: com
|
2656
|
-
*
|
2657
2690
|
* call-seq:
|
2658
2691
|
* a.com
|
2659
2692
|
*
|
@@ -2661,7 +2694,6 @@ DEFUN_INT_LOGIC(xor, mpz_xor)
|
|
2661
2694
|
*/
|
2662
2695
|
/*
|
2663
2696
|
* Document-method: com!
|
2664
|
-
*
|
2665
2697
|
* call-seq:
|
2666
2698
|
* a.com!
|
2667
2699
|
*
|
@@ -2671,13 +2703,13 @@ DEFUN_INT2INT(com, mpz_com)
|
|
2671
2703
|
|
2672
2704
|
/*
|
2673
2705
|
* Document-method: popcount
|
2674
|
-
*
|
2675
2706
|
* call-seq:
|
2676
2707
|
* a.popcount
|
2677
2708
|
*
|
2678
|
-
* If _a_ >= 0, return the population count of _a_, which is the number of 1
|
2679
|
-
* binary representation. If _a_ < 0, the number of 1s is infinite,
|
2680
|
-
* is INT2FIX(ULONG_MAX)
|
2709
|
+
* If _a_ >= 0, return the population count of _a_, which is the number of 1
|
2710
|
+
* bits in the binary representation. If _a_ < 0, the number of 1s is infinite,
|
2711
|
+
* and the return value is `INT2FIX(ULONG_MAX)`, the largest possible unsigned
|
2712
|
+
* long.
|
2681
2713
|
*/
|
2682
2714
|
VALUE r_gmpz_popcount(VALUE self)
|
2683
2715
|
{
|
@@ -2687,11 +2719,13 @@ VALUE r_gmpz_popcount(VALUE self)
|
|
2687
2719
|
}
|
2688
2720
|
|
2689
2721
|
/*
|
2722
|
+
* Document-method: hamdist
|
2690
2723
|
* call-seq:
|
2691
2724
|
* a.hamdist(b)
|
2692
2725
|
*
|
2693
|
-
* If _a_ and _b_ are both >= 0 or both < 0, calculate the hamming distance
|
2694
|
-
*
|
2726
|
+
* If _a_ and _b_ are both >= 0 or both < 0, calculate the hamming distance
|
2727
|
+
* between _a_ and _b_. If one operand is >= 0 and the other is less than 0,
|
2728
|
+
* then return "infinity" (the largest possible `mp_bitcnt_t`).
|
2695
2729
|
*/
|
2696
2730
|
VALUE r_gmpz_hamdist(VALUE self_val, VALUE b_val)
|
2697
2731
|
{
|
@@ -2706,22 +2740,24 @@ VALUE r_gmpz_hamdist(VALUE self_val, VALUE b_val)
|
|
2706
2740
|
}
|
2707
2741
|
|
2708
2742
|
/*
|
2743
|
+
* Document-method: scan0
|
2709
2744
|
* call-seq:
|
2710
2745
|
* a.scan0(starting_bit)
|
2711
2746
|
*
|
2712
|
-
* Scan _a_, starting from bit _starting_bit_, towards more significant bits,
|
2713
|
-
* first 0 bit is found. Return the index of the found bit.
|
2747
|
+
* Scan _a_, starting from bit _starting_bit_, towards more significant bits,
|
2748
|
+
* until the first 0 bit is found. Return the index of the found bit.
|
2714
2749
|
*
|
2715
|
-
* If the bit at _starting_bit_ is already what's sought, then _starting_bit_
|
2716
|
-
* returned.
|
2750
|
+
* If the bit at _starting_bit_ is already what's sought, then _starting_bit_
|
2751
|
+
* is returned.
|
2717
2752
|
*
|
2718
|
-
* If there's no bit found, then INT2FIX(ULONG_MAX) is returned. This will
|
2719
|
-
* scan0 past the end of a negative number.
|
2753
|
+
* If there's no bit found, then `INT2FIX(ULONG_MAX)` is returned. This will
|
2754
|
+
* happen in #scan0 past the end of a negative number.
|
2720
2755
|
*/
|
2721
2756
|
VALUE r_gmpz_scan0(VALUE self, VALUE bitnr)
|
2722
2757
|
{
|
2723
2758
|
MP_INT *self_val;
|
2724
|
-
int bitnr_val;
|
2759
|
+
int bitnr_val = 0;
|
2760
|
+
|
2725
2761
|
mpz_get_struct (self, self_val);
|
2726
2762
|
if (FIXNUM_P (bitnr)) {
|
2727
2763
|
bitnr_val = FIX2INT (bitnr);
|
@@ -2732,22 +2768,23 @@ VALUE r_gmpz_scan0(VALUE self, VALUE bitnr)
|
|
2732
2768
|
}
|
2733
2769
|
|
2734
2770
|
/*
|
2771
|
+
* Document-method: scan1
|
2735
2772
|
* call-seq:
|
2736
2773
|
* a.scan1(starting_bit)
|
2737
2774
|
*
|
2738
|
-
* Scan _a_, starting from bit _starting_bit_, towards more significant bits,
|
2739
|
-
* first 1 bit is found. Return the index of the found bit.
|
2775
|
+
* Scan _a_, starting from bit _starting_bit_, towards more significant bits,
|
2776
|
+
* until the first 1 bit is found. Return the index of the found bit.
|
2740
2777
|
*
|
2741
|
-
* If the bit at _starting_bit_ is already what's sought, then _starting_bit_
|
2742
|
-
* returned.
|
2778
|
+
* If the bit at _starting_bit_ is already what's sought, then _starting_bit_
|
2779
|
+
* is returned.
|
2743
2780
|
*
|
2744
|
-
* If there's no bit found, then INT2FIX(ULONG_MAX) is returned. This will
|
2745
|
-
* scan1 past the end of a nonnegative number.
|
2781
|
+
* If there's no bit found, then `INT2FIX(ULONG_MAX)` is returned. This will
|
2782
|
+
* happen in scan1 past the end of a nonnegative number.
|
2746
2783
|
*/
|
2747
2784
|
VALUE r_gmpz_scan1(VALUE self, VALUE bitnr)
|
2748
2785
|
{
|
2749
2786
|
MP_INT *self_val;
|
2750
|
-
int bitnr_val;
|
2787
|
+
int bitnr_val = 0;
|
2751
2788
|
|
2752
2789
|
mpz_get_struct (self, self_val);
|
2753
2790
|
|
@@ -2761,6 +2798,7 @@ VALUE r_gmpz_scan1(VALUE self, VALUE bitnr)
|
|
2761
2798
|
}
|
2762
2799
|
|
2763
2800
|
/*
|
2801
|
+
* Document-method: []=
|
2764
2802
|
* call-seq:
|
2765
2803
|
* a[index] = x
|
2766
2804
|
*
|
@@ -2769,18 +2807,19 @@ VALUE r_gmpz_scan1(VALUE self, VALUE bitnr)
|
|
2769
2807
|
VALUE r_gmpz_setbit(VALUE self, VALUE bitnr, VALUE set_to)
|
2770
2808
|
{
|
2771
2809
|
MP_INT *self_val;
|
2772
|
-
unsigned long bitnr_val;
|
2810
|
+
unsigned long bitnr_val = 0;
|
2773
2811
|
|
2774
2812
|
mpz_get_struct (self, self_val);
|
2775
2813
|
|
2776
2814
|
if (FIXNUM_P (bitnr)) {
|
2777
2815
|
if (FIX2NUM (bitnr) < 0) {
|
2778
|
-
rb_raise(rb_eRangeError, "index must be nonnegative");
|
2816
|
+
rb_raise (rb_eRangeError, "index must be nonnegative");
|
2779
2817
|
}
|
2780
2818
|
bitnr_val = FIX2NUM (bitnr);
|
2781
2819
|
} else {
|
2782
2820
|
typeerror_as (X, "index");
|
2783
2821
|
}
|
2822
|
+
|
2784
2823
|
if (RTEST (set_to)) {
|
2785
2824
|
mpz_setbit (self_val, bitnr_val);
|
2786
2825
|
} else {
|
@@ -2790,6 +2829,7 @@ VALUE r_gmpz_setbit(VALUE self, VALUE bitnr, VALUE set_to)
|
|
2790
2829
|
}
|
2791
2830
|
|
2792
2831
|
/*
|
2832
|
+
* Document-method: []
|
2793
2833
|
* call-seq:
|
2794
2834
|
* a[index] #=> boolean
|
2795
2835
|
*
|
@@ -2798,14 +2838,15 @@ VALUE r_gmpz_setbit(VALUE self, VALUE bitnr, VALUE set_to)
|
|
2798
2838
|
VALUE r_gmpz_getbit(VALUE self, VALUE bitnr)
|
2799
2839
|
{
|
2800
2840
|
MP_INT *self_val;
|
2801
|
-
unsigned long bitnr_val;
|
2802
|
-
|
2803
|
-
|
2841
|
+
unsigned long bitnr_val = 0;
|
2842
|
+
|
2843
|
+
mpz_get_struct (self, self_val);
|
2844
|
+
if (FIXNUM_P (bitnr)) {
|
2804
2845
|
bitnr_val = FIX2NUM (bitnr);
|
2805
2846
|
} else {
|
2806
|
-
typeerror_as(X, "index");
|
2847
|
+
typeerror_as (X, "index");
|
2807
2848
|
}
|
2808
|
-
return mpz_tstbit(self_val, bitnr_val)?Qtrue:Qfalse;
|
2849
|
+
return mpz_tstbit (self_val, bitnr_val) ? Qtrue : Qfalse;
|
2809
2850
|
}
|
2810
2851
|
|
2811
2852
|
|
@@ -2814,6 +2855,7 @@ VALUE r_gmpz_getbit(VALUE self, VALUE bitnr)
|
|
2814
2855
|
**********************************************************************/
|
2815
2856
|
|
2816
2857
|
/*
|
2858
|
+
* Document-method: out_raw
|
2817
2859
|
* call-seq:
|
2818
2860
|
* a.out_raw(stream) #=> Fixnum
|
2819
2861
|
*
|
@@ -2840,6 +2882,7 @@ VALUE r_gmpz_out_raw(VALUE self, VALUE stream)
|
|
2840
2882
|
}
|
2841
2883
|
|
2842
2884
|
/*
|
2885
|
+
* Document-method: inp_raw
|
2843
2886
|
* call-seq:
|
2844
2887
|
* GMP::Z.inp_raw(a, stream) #=> Fixnum
|
2845
2888
|
*
|
@@ -2871,14 +2914,18 @@ VALUE r_gmpzsg_inp_raw(VALUE klass, VALUE a_val, VALUE stream_val)
|
|
2871
2914
|
**********************************************************************/
|
2872
2915
|
|
2873
2916
|
/*
|
2917
|
+
* Document-method: import
|
2874
2918
|
* call-seq:
|
2875
2919
|
* GMP::Z.import(str, order = -1) #=> GMP::Z
|
2876
2920
|
*
|
2877
2921
|
* Return a GMP::Z from a String, `str`.
|
2878
2922
|
*
|
2879
|
-
* `order` can be 1 for most significant word first or -1 for least significant
|
2923
|
+
* `order` can be 1 for most significant word first or -1 for least significant
|
2924
|
+
* first.
|
2880
2925
|
*
|
2881
|
-
* There is no sign taken from the data, the result will simply be a positive
|
2926
|
+
* There is no sign taken from the data, the result will simply be a positive
|
2927
|
+
* integer. An application can handle any sign itself, and apply it for
|
2928
|
+
* instance with `GMP::Z#neg`.
|
2882
2929
|
*/
|
2883
2930
|
VALUE r_gmpzsg_import(int argc, VALUE *argv, VALUE klass)
|
2884
2931
|
{
|
@@ -2891,6 +2938,7 @@ VALUE r_gmpzsg_import(int argc, VALUE *argv, VALUE klass)
|
|
2891
2938
|
|
2892
2939
|
endian = 0;
|
2893
2940
|
nails = 0;
|
2941
|
+
order = 1;
|
2894
2942
|
|
2895
2943
|
rb_scan_args (argc, argv, "11", &string_val, &order_val);
|
2896
2944
|
|
@@ -2911,6 +2959,7 @@ VALUE r_gmpzsg_import(int argc, VALUE *argv, VALUE klass)
|
|
2911
2959
|
}
|
2912
2960
|
|
2913
2961
|
/*
|
2962
|
+
* Document-method: export
|
2914
2963
|
* call-seq:
|
2915
2964
|
* a.export(order = -1) #=> String
|
2916
2965
|
*
|
@@ -2935,6 +2984,7 @@ VALUE r_gmpz_export(int argc, VALUE *argv, VALUE self_val)
|
|
2935
2984
|
|
2936
2985
|
endian = 0;
|
2937
2986
|
nails = 0;
|
2987
|
+
order = 1;
|
2938
2988
|
mpz_get_struct(self_val, self);
|
2939
2989
|
|
2940
2990
|
rb_scan_args (argc, argv, "01", &order_val);
|
@@ -2960,7 +3010,6 @@ VALUE r_gmpz_export(int argc, VALUE *argv, VALUE self_val)
|
|
2960
3010
|
|
2961
3011
|
/*
|
2962
3012
|
* Document-method: even?
|
2963
|
-
*
|
2964
3013
|
* call-seq:
|
2965
3014
|
* a.even?
|
2966
3015
|
*
|
@@ -2969,7 +3018,6 @@ VALUE r_gmpz_export(int argc, VALUE *argv, VALUE self_val)
|
|
2969
3018
|
DEFUN_INT_COND_P(is_even,mpz_even_p)
|
2970
3019
|
/*
|
2971
3020
|
* Document-method: odd?
|
2972
|
-
*
|
2973
3021
|
* call-seq:
|
2974
3022
|
* a.odd?
|
2975
3023
|
*
|
@@ -2978,16 +3026,17 @@ DEFUN_INT_COND_P(is_even,mpz_even_p)
|
|
2978
3026
|
DEFUN_INT_COND_P(is_odd,mpz_odd_p)
|
2979
3027
|
|
2980
3028
|
/*
|
3029
|
+
* Document-method: sizeinbase
|
2981
3030
|
* call-seq:
|
2982
|
-
* a.sizeinbase
|
2983
|
-
* a.size_in_base
|
3031
|
+
* a.sizeinbase(base)
|
3032
|
+
* a.size_in_base(base)
|
2984
3033
|
*
|
2985
3034
|
* @since 0.2.11
|
2986
3035
|
*
|
2987
|
-
* Return the size of _a_ measured in number of digits in
|
2988
|
-
* from 2 to 62. The sign of _a_ is ignored, just the absolute value is
|
2989
|
-
* will be either exact or 1 too big. If base is a power of
|
2990
|
-
* exact. If _a_ is zero the return value is always 1.
|
3036
|
+
* Return the size of _a_ measured in number of digits in `base`. `base` can
|
3037
|
+
* vary from 2 to 62. The sign of _a_ is ignored, just the absolute value is
|
3038
|
+
* used. The result will be either exact or 1 too big. If `base` is a power of
|
3039
|
+
* 2, the result is always exact. If _a_ is zero the return value is always 1.
|
2991
3040
|
*/
|
2992
3041
|
VALUE r_gmpz_sizeinbase(VALUE self, VALUE base)
|
2993
3042
|
{
|
@@ -2999,13 +3048,15 @@ VALUE r_gmpz_sizeinbase(VALUE self, VALUE base)
|
|
2999
3048
|
}
|
3000
3049
|
|
3001
3050
|
/*
|
3051
|
+
* Document-method: size_in_bin
|
3002
3052
|
* call-seq:
|
3003
3053
|
* a.size_in_bin
|
3004
3054
|
*
|
3005
3055
|
* @since 0.2.11
|
3006
3056
|
*
|
3007
|
-
* Return the size of _a_ measured in number of digits in binary. The sign of
|
3008
|
-
* ignored, just the absolute value is used. If _a_ is zero the return
|
3057
|
+
* Return the size of _a_ measured in number of digits in binary. The sign of
|
3058
|
+
* _a_ is ignored, just the absolute value is used. If _a_ is zero the return
|
3059
|
+
* value is 1.
|
3009
3060
|
*/
|
3010
3061
|
VALUE r_gmpz_size_in_bin(VALUE self)
|
3011
3062
|
{
|
@@ -3020,13 +3071,14 @@ VALUE r_gmpz_size_in_bin(VALUE self)
|
|
3020
3071
|
**********************************************************************/
|
3021
3072
|
|
3022
3073
|
/*
|
3074
|
+
* Document-method: size
|
3023
3075
|
* call-seq:
|
3024
3076
|
* a.size
|
3025
3077
|
*
|
3026
3078
|
* @since 0.4.19
|
3027
3079
|
*
|
3028
|
-
* Return the size of _a_ measured in number of limbs. If _a_ is zero, the
|
3029
|
-
* value will be zero.
|
3080
|
+
* Return the size of _a_ measured in number of limbs. If _a_ is zero, the
|
3081
|
+
* returned value will be zero.
|
3030
3082
|
*/
|
3031
3083
|
VALUE r_gmpz_size(VALUE self)
|
3032
3084
|
{
|