gmp 0.6.47 → 0.7.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
{
|