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/gmpq.c
CHANGED
@@ -7,9 +7,9 @@
|
|
7
7
|
*
|
8
8
|
* GMP Multiple Precision Rational Number.
|
9
9
|
*
|
10
|
-
* Instances of this class can store variables of the type mpq_t
|
11
|
-
* contains many methods that act as the functions for mpq_t variables,
|
12
|
-
* methods that attempt to make this library more Ruby-ish.
|
10
|
+
* Instances of this class can store variables of the type `mpq_t`. This class
|
11
|
+
* also contains many methods that act as the functions for `mpq_t` variables,
|
12
|
+
* as well as a few methods that attempt to make this library more Ruby-ish.
|
13
13
|
*/
|
14
14
|
|
15
15
|
/**********************************************************************
|
@@ -38,9 +38,9 @@ static VALUE r_gmpq_##fname(VALUE self) \
|
|
38
38
|
}
|
39
39
|
|
40
40
|
/*
|
41
|
-
* DEFUN_RAT2RAT defines two functions. The first takes a GMP::Q as self, calls
|
42
|
-
* on the contained mpq_t, whose arguments are exactly (0) the return
|
43
|
-
* self. The second is the same destructive method.
|
41
|
+
* DEFUN_RAT2RAT defines two functions. The first takes a GMP::Q as self, calls
|
42
|
+
* mpq_fname on the contained mpq_t, whose arguments are exactly (0) the return
|
43
|
+
* argument and (1) self. The second is the same destructive method.
|
44
44
|
*/
|
45
45
|
#define DEFUN_RAT2RAT(fname,mpq_fname) \
|
46
46
|
static VALUE r_gmpq_##fname(VALUE self) \
|
@@ -82,7 +82,7 @@ VALUE r_gmpqsg_new(int argc, VALUE *argv, VALUE klass)
|
|
82
82
|
(void)klass;
|
83
83
|
|
84
84
|
if (argc > 2)
|
85
|
-
rb_raise (rb_eArgError, "wrong
|
85
|
+
rb_raise (rb_eArgError, "wrong number of arguments (%d for 0, 1 or 2)", argc);
|
86
86
|
|
87
87
|
mpq_make_struct (res, res_val);
|
88
88
|
mpq_init (res_val);
|
@@ -113,21 +113,45 @@ static void mpq_str_set(MP_RAT *ROP, char *str)
|
|
113
113
|
|
114
114
|
VALUE r_gmpq_initialize(int argc, VALUE *argv, VALUE self)
|
115
115
|
{
|
116
|
-
MP_RAT *self_val, *
|
116
|
+
MP_RAT *self_val, *arg_val_q;
|
117
|
+
MP_INT *arg_z;
|
117
118
|
|
118
119
|
if (argc != 0) {
|
119
120
|
mpq_get_struct (self, self_val);
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
121
|
+
/* TODO: use mpq_set_f */
|
122
|
+
if (argc == 1) {
|
123
|
+
if (FIXNUM_P (argv[0])) {
|
124
|
+
if (FIX2NUM (argv[0]) >= 0)
|
125
|
+
mpq_set_ui (self_val, FIX2NUM (argv[0]), 1);
|
126
|
+
else
|
127
|
+
mpq_set_si (self_val, FIX2NUM (argv[0]), 1);
|
128
|
+
} else if (GMPZ_P (argv[0])) {
|
129
|
+
mpz_get_struct (argv[0], arg_z);
|
130
|
+
mpq_set_z (self_val, arg_z);
|
131
|
+
} else if (FLOAT_P (argv[0])) {
|
132
|
+
mpq_set_d (self_val, NUM2DBL (argv[0]));
|
133
|
+
} else if (GMPQ_P (argv[0])) {
|
134
|
+
mpq_get_struct (argv[0], arg_val_q);
|
135
|
+
mpq_set (self_val, arg_val_q);
|
136
|
+
} else if (STRING_P (argv[0])) {
|
137
|
+
mpq_str_set (self_val, StringValuePtr (argv[0]));
|
138
|
+
} else {
|
139
|
+
mpz_set_value (mpq_numref (self_val), argv[0], 0); /* are these segfaulting? */
|
140
|
+
}
|
141
|
+
} else if (argc == 2) {
|
142
|
+
if (FIXNUM_P (argv[0]) && FIXNUM_P (argv[1]) && FIX2NUM (argv[1]) >= 0) {
|
143
|
+
if (FIX2NUM (argv[0]) >= 0)
|
144
|
+
mpq_set_ui (self_val, FIX2NUM (argv[0]), FIX2NUM (argv[1]));
|
145
|
+
else
|
146
|
+
mpq_set_si (self_val, FIX2NUM (argv[0]), FIX2NUM (argv[1]));
|
147
|
+
} else {
|
148
|
+
mpz_set_value (mpq_numref (self_val), argv[0], 0); /* are these segfaulting? */
|
149
|
+
mpz_set_value (mpq_denref (self_val), argv[1], 0); /* are these segfaulting? */
|
150
|
+
}
|
151
|
+
|
152
|
+
mpq_canonicalize (self_val);
|
125
153
|
} else {
|
126
|
-
|
127
|
-
if (argc == 2) {
|
128
|
-
mpz_set_value (mpq_denref (self_val), argv[1], 0); // are these segfaulting?
|
129
|
-
mpq_canonicalize (self_val);
|
130
|
-
} // AND IF ARGC != 2 ?!? WHAT JUST HAPPENED?
|
154
|
+
rb_raise (rb_eArgError, "wrong number of arguments (%d for 0, 1, or 2)", argc);
|
131
155
|
}
|
132
156
|
}
|
133
157
|
return Qnil;
|
@@ -146,6 +170,7 @@ VALUE r_gmpmod_q(int argc, VALUE *argv, VALUE module)
|
|
146
170
|
}
|
147
171
|
|
148
172
|
/*
|
173
|
+
* Document-method: swap
|
149
174
|
* call-seq:
|
150
175
|
* p.swap(q)
|
151
176
|
*
|
@@ -172,27 +197,30 @@ VALUE r_gmpq_swap (VALUE self, VALUE arg)
|
|
172
197
|
**********************************************************************/
|
173
198
|
|
174
199
|
/*
|
200
|
+
* Document-method: to_d
|
175
201
|
* call-seq:
|
176
202
|
* p.to_d
|
177
203
|
*
|
178
204
|
* Returns _p_ as an Float if _p_ fits in a Float.
|
179
205
|
*
|
180
|
-
* Otherwise returns the least significant part of _p_, with the same sign as
|
206
|
+
* Otherwise returns the least significant part of _p_, with the same sign as
|
207
|
+
* _p_.
|
181
208
|
*
|
182
|
-
* If the exponent from the conversion is too big or too small to fit a double
|
183
|
-
* result is system dependent. For too big an infinity is returned
|
184
|
-
* too small 0.0 is normally returned. Hardware overflow,
|
185
|
-
* or may not occur.
|
209
|
+
* If the exponent from the conversion is too big or too small to fit a double
|
210
|
+
* then the result is system dependent. For too big an infinity is returned
|
211
|
+
* when available. For too small 0.0 is normally returned. Hardware overflow,
|
212
|
+
* underflow and denorm traps may or may not occur.
|
186
213
|
*/
|
187
214
|
VALUE r_gmpq_to_d(VALUE self)
|
188
215
|
{
|
189
216
|
MP_RAT *self_val;
|
190
|
-
mpq_get_struct(self, self_val);
|
217
|
+
mpq_get_struct (self, self_val);
|
191
218
|
|
192
|
-
return rb_float_new(mpq_get_d(self_val));
|
219
|
+
return rb_float_new (mpq_get_d (self_val));
|
193
220
|
}
|
194
221
|
|
195
222
|
/*
|
223
|
+
* Document-method: to_s
|
196
224
|
* call-seq:
|
197
225
|
* p.to_s
|
198
226
|
*
|
@@ -207,8 +235,7 @@ VALUE r_gmpq_to_s(VALUE self)
|
|
207
235
|
size_t sizeinbase;
|
208
236
|
size_t offset;
|
209
237
|
|
210
|
-
|
211
|
-
mpq_get_struct(self, self_val)
|
238
|
+
mpq_get_struct (self, self_val)
|
212
239
|
|
213
240
|
if (mpz_cmp_ui (mpq_denref (self_val), 1) == 0) {
|
214
241
|
str = mpz_get_str (NULL, 10, mpq_numref (self_val));
|
@@ -227,7 +254,7 @@ VALUE r_gmpq_to_s(VALUE self)
|
|
227
254
|
offset = strlen (str);
|
228
255
|
str[offset] = '/';
|
229
256
|
mpz_get_str (str + offset + 1, 10, self_val_den);
|
230
|
-
res = rb_str_new2(str);
|
257
|
+
res = rb_str_new2 (str);
|
231
258
|
free (str);
|
232
259
|
|
233
260
|
return res;
|
@@ -239,10 +266,12 @@ VALUE r_gmpq_to_s(VALUE self)
|
|
239
266
|
**********************************************************************/
|
240
267
|
|
241
268
|
/*
|
269
|
+
* Document-method: +
|
242
270
|
* call-seq:
|
243
271
|
* p + q
|
244
272
|
*
|
245
273
|
* Adds _p_ to _q_. _q_ must be an instance of one of:
|
274
|
+
*
|
246
275
|
* * GMP::Z
|
247
276
|
* * Fixnum
|
248
277
|
* * GMP::Q
|
@@ -255,46 +284,48 @@ VALUE r_gmpq_add(VALUE self, VALUE arg)
|
|
255
284
|
MP_INT *arg_val_z, *res_val_num;
|
256
285
|
VALUE res;
|
257
286
|
|
258
|
-
mpq_get_struct(self, self_val);
|
259
|
-
mpq_make_struct_init(res, res_val);
|
260
|
-
|
261
|
-
if (GMPQ_P(arg)) {
|
262
|
-
mpq_get_struct(arg,arg_val_q);
|
263
|
-
mpq_add(res_val, self_val, arg_val_q);
|
264
|
-
} else if (GMPZ_P(arg)) {
|
265
|
-
res_val_num = mpq_numref(res_val);
|
266
|
-
mpz_set(mpq_denref(res_val), mpq_denref(self_val));
|
267
|
-
mpz_get_struct(arg, arg_val_z);
|
268
|
-
mpz_mul(res_val_num, mpq_denref(self_val), arg_val_z);
|
269
|
-
mpz_add(res_val_num, res_val_num, mpq_numref(self_val));
|
270
|
-
} else if (FIXNUM_P(arg)) {
|
271
|
-
res_val_num = mpq_numref(res_val);
|
272
|
-
mpz_set(mpq_denref(res_val), mpq_denref(self_val));
|
273
|
-
mpz_mul_si(res_val_num, mpq_denref(self_val), FIX2NUM(arg));
|
274
|
-
mpz_add(res_val_num, res_val_num, mpq_numref(self_val));
|
275
|
-
} else if (GMPF_P(arg)) {
|
287
|
+
mpq_get_struct (self, self_val);
|
288
|
+
mpq_make_struct_init (res, res_val);
|
289
|
+
|
290
|
+
if (GMPQ_P (arg)) {
|
291
|
+
mpq_get_struct (arg,arg_val_q);
|
292
|
+
mpq_add (res_val, self_val, arg_val_q);
|
293
|
+
} else if (GMPZ_P (arg)) {
|
294
|
+
res_val_num = mpq_numref (res_val);
|
295
|
+
mpz_set (mpq_denref (res_val), mpq_denref (self_val));
|
296
|
+
mpz_get_struct (arg, arg_val_z);
|
297
|
+
mpz_mul (res_val_num, mpq_denref (self_val), arg_val_z);
|
298
|
+
mpz_add (res_val_num, res_val_num, mpq_numref (self_val));
|
299
|
+
} else if (FIXNUM_P (arg)) {
|
300
|
+
res_val_num = mpq_numref (res_val);
|
301
|
+
mpz_set (mpq_denref (res_val), mpq_denref (self_val));
|
302
|
+
mpz_mul_si (res_val_num, mpq_denref (self_val), FIX2NUM (arg));
|
303
|
+
mpz_add (res_val_num, res_val_num, mpq_numref (self_val));
|
304
|
+
} else if (GMPF_P (arg)) {
|
276
305
|
#ifndef MPFR
|
277
|
-
return r_gmpf_add(arg,self);
|
306
|
+
return r_gmpf_add (arg,self);
|
278
307
|
#else
|
279
|
-
return rb_funcall(arg, rb_intern("+"), 1, self);
|
308
|
+
return rb_funcall (arg, rb_intern ("+"), 1, self);
|
280
309
|
#endif
|
281
|
-
} else if (BIGNUM_P(arg)) {
|
282
|
-
res_val_num = mpq_numref(res_val);
|
283
|
-
mpz_set(mpq_denref(res_val), mpq_denref(self_val));
|
284
|
-
mpz_set_bignum(res_val_num, arg);
|
285
|
-
mpz_mul(res_val_num, res_val_num, mpq_denref(self_val));
|
286
|
-
mpz_add(res_val_num, res_val_num, mpq_numref(self_val));
|
310
|
+
} else if (BIGNUM_P (arg)) {
|
311
|
+
res_val_num = mpq_numref (res_val);
|
312
|
+
mpz_set (mpq_denref (res_val), mpq_denref (self_val));
|
313
|
+
mpz_set_bignum (res_val_num, arg);
|
314
|
+
mpz_mul (res_val_num, res_val_num, mpq_denref (self_val));
|
315
|
+
mpz_add (res_val_num, res_val_num, mpq_numref (self_val));
|
287
316
|
} else {
|
288
|
-
typeerror(ZQFXB);
|
317
|
+
typeerror (ZQFXB);
|
289
318
|
}
|
290
319
|
return res;
|
291
320
|
}
|
292
321
|
|
293
322
|
/*
|
323
|
+
* Document-method: -
|
294
324
|
* call-seq:
|
295
325
|
* p - q
|
296
326
|
*
|
297
327
|
* Subtracts _p_ from _q_. _q_ must be an instance of one of:
|
328
|
+
*
|
298
329
|
* * GMP::Z
|
299
330
|
* * Fixnum
|
300
331
|
* * GMP::Q
|
@@ -309,36 +340,36 @@ VALUE r_gmpq_sub(VALUE self, VALUE arg)
|
|
309
340
|
VALUE res;
|
310
341
|
mpfr_prec_t prec;
|
311
342
|
|
312
|
-
mpq_get_struct(self, self_val);
|
313
|
-
mpq_make_struct_init(res, res_val);
|
343
|
+
mpq_get_struct (self, self_val);
|
344
|
+
mpq_make_struct_init (res, res_val);
|
314
345
|
|
315
|
-
if (GMPQ_P(arg)) {
|
316
|
-
mpq_get_struct(arg,arg_val_q);
|
346
|
+
if (GMPQ_P (arg)) {
|
347
|
+
mpq_get_struct (arg,arg_val_q);
|
317
348
|
mpq_sub (res_val, self_val, arg_val_q);
|
318
|
-
} else if (GMPZ_P(arg)) {
|
319
|
-
res_val_num = mpq_numref(res_val);
|
320
|
-
mpz_set (mpq_denref(res_val), mpq_denref(self_val));
|
321
|
-
mpz_get_struct(arg, arg_val_z);
|
322
|
-
mpz_mul (res_val_num, mpq_denref(self_val), arg_val_z);
|
349
|
+
} else if (GMPZ_P (arg)) {
|
350
|
+
res_val_num = mpq_numref (res_val);
|
351
|
+
mpz_set (mpq_denref (res_val), mpq_denref (self_val));
|
352
|
+
mpz_get_struct (arg, arg_val_z);
|
353
|
+
mpz_mul (res_val_num, mpq_denref (self_val), arg_val_z);
|
323
354
|
mpz_neg (res_val_num, res_val_num);
|
324
|
-
mpz_add (res_val_num, res_val_num, mpq_numref(self_val));
|
325
|
-
} else if (FIXNUM_P(arg)) {
|
326
|
-
res_val_num = mpq_numref(res_val);
|
327
|
-
mpz_set (mpq_denref(res_val), mpq_denref(self_val));
|
328
|
-
mpz_mul_si (res_val_num, mpq_denref(self_val), -FIX2NUM(arg));
|
329
|
-
mpz_add (res_val_num, res_val_num, mpq_numref(self_val));
|
330
|
-
} else if (GMPF_P(arg)) {
|
355
|
+
mpz_add (res_val_num, res_val_num, mpq_numref (self_val));
|
356
|
+
} else if (FIXNUM_P (arg)) {
|
357
|
+
res_val_num = mpq_numref (res_val);
|
358
|
+
mpz_set (mpq_denref (res_val), mpq_denref (self_val));
|
359
|
+
mpz_mul_si (res_val_num, mpq_denref (self_val), -FIX2NUM (arg));
|
360
|
+
mpz_add (res_val_num, res_val_num, mpq_numref (self_val));
|
361
|
+
} else if (GMPF_P (arg)) {
|
331
362
|
mpf_get_struct_prec (arg, arg_val_f, prec);
|
332
|
-
mpf_make_struct_init(res, res_val_f, prec);
|
363
|
+
mpf_make_struct_init (res, res_val_f, prec);
|
333
364
|
mpf_set_q (res_val_f, self_val);
|
334
365
|
mpf_sub (res_val_f, res_val_f, arg_val_f);
|
335
|
-
} else if (BIGNUM_P(arg)) {
|
336
|
-
res_val_num = mpq_numref(res_val);
|
337
|
-
mpz_set (mpq_denref(res_val), mpq_denref(self_val));
|
366
|
+
} else if (BIGNUM_P (arg)) {
|
367
|
+
res_val_num = mpq_numref (res_val);
|
368
|
+
mpz_set (mpq_denref (res_val), mpq_denref (self_val));
|
338
369
|
mpz_set_bignum (res_val_num, arg);
|
339
|
-
mpz_mul (res_val_num, res_val_num, mpq_denref(self_val));
|
370
|
+
mpz_mul (res_val_num, res_val_num, mpq_denref (self_val));
|
340
371
|
mpz_neg (res_val_num, res_val_num);
|
341
|
-
mpz_add (res_val_num, res_val_num, mpq_numref(self_val));
|
372
|
+
mpz_add (res_val_num, res_val_num, mpq_numref (self_val));
|
342
373
|
} else {
|
343
374
|
typeerror (ZQFXB);
|
344
375
|
}
|
@@ -346,10 +377,12 @@ VALUE r_gmpq_sub(VALUE self, VALUE arg)
|
|
346
377
|
}
|
347
378
|
|
348
379
|
/*
|
380
|
+
* Document-method: *
|
349
381
|
* call-seq:
|
350
382
|
* p * q
|
351
383
|
*
|
352
384
|
* Multiplies _p_ with _q_. _q_ must be an instance of one of:
|
385
|
+
*
|
353
386
|
* * GMP::Z
|
354
387
|
* * Fixnum
|
355
388
|
* * GMP::Q
|
@@ -418,10 +451,12 @@ VALUE r_gmpq_mul(VALUE self, VALUE arg)
|
|
418
451
|
}
|
419
452
|
|
420
453
|
/*
|
454
|
+
* Document-method: /
|
421
455
|
* call-seq:
|
422
456
|
* p / q
|
423
457
|
*
|
424
458
|
* Divides _p_ by _q_. _q_ must be an instance of one of:
|
459
|
+
*
|
425
460
|
* * GMP::Z
|
426
461
|
* * Fixnum
|
427
462
|
* * GMP::Q
|
@@ -487,7 +522,6 @@ DEFUN_RAT2INT(ceil,mpz_cdiv_q)
|
|
487
522
|
|
488
523
|
/*
|
489
524
|
* Document-method: neg
|
490
|
-
*
|
491
525
|
* call-seq:
|
492
526
|
* a.neg
|
493
527
|
* -a
|
@@ -496,7 +530,6 @@ DEFUN_RAT2INT(ceil,mpz_cdiv_q)
|
|
496
530
|
*/
|
497
531
|
/*
|
498
532
|
* Document-method: neg!
|
499
|
-
*
|
500
533
|
* call-seq:
|
501
534
|
* a.neg!
|
502
535
|
*
|
@@ -505,12 +538,14 @@ DEFUN_RAT2INT(ceil,mpz_cdiv_q)
|
|
505
538
|
DEFUN_RAT2RAT(neg, mpq_neg)
|
506
539
|
|
507
540
|
/*
|
541
|
+
* Document-method: abs
|
508
542
|
* call-seq:
|
509
543
|
* p.abs
|
510
544
|
*
|
511
545
|
* Returns the absolute value of _p_.
|
512
546
|
*/
|
513
547
|
/*
|
548
|
+
* Document-method: abs!
|
514
549
|
* call-seq:
|
515
550
|
* p.abs!
|
516
551
|
*
|
@@ -519,10 +554,11 @@ DEFUN_RAT2RAT(neg, mpq_neg)
|
|
519
554
|
DEFUN_RAT2RAT(abs, mpq_abs)
|
520
555
|
|
521
556
|
/*
|
557
|
+
* Document-method: inv
|
522
558
|
* call-seq:
|
523
559
|
* p.inv
|
524
560
|
*
|
525
|
-
* Returns
|
561
|
+
* Returns _1/p_.
|
526
562
|
*/
|
527
563
|
VALUE r_gmpq_inv(VALUE self)
|
528
564
|
{
|
@@ -539,10 +575,11 @@ VALUE r_gmpq_inv(VALUE self)
|
|
539
575
|
}
|
540
576
|
|
541
577
|
/*
|
578
|
+
* Document-method: inv!
|
542
579
|
* call-seq:
|
543
580
|
* p.inv!
|
544
581
|
*
|
545
|
-
* Sets _p_ to
|
582
|
+
* Sets _p_ to _1/p_.
|
546
583
|
*/
|
547
584
|
VALUE r_gmpq_inv_self(VALUE self)
|
548
585
|
{
|
@@ -594,8 +631,17 @@ int mpq_cmp_value(MP_RAT *OP, VALUE arg)
|
|
594
631
|
} else {
|
595
632
|
typeerror(ZQFXB);
|
596
633
|
}
|
634
|
+
|
635
|
+
return 0; /* should never get here */
|
597
636
|
}
|
598
637
|
|
638
|
+
/*
|
639
|
+
* Document-method: ==
|
640
|
+
* call-seq:
|
641
|
+
* a == b
|
642
|
+
*
|
643
|
+
* Returns true if _a_ is equal to _b_, and false otherwise.
|
644
|
+
*/
|
599
645
|
VALUE r_gmpq_eq(VALUE self, VALUE arg)
|
600
646
|
{
|
601
647
|
MP_RAT *self_val, *arg_val_q;
|
@@ -613,7 +659,7 @@ VALUE r_gmpq_eq(VALUE self, VALUE arg)
|
|
613
659
|
} else if (FIXNUM_P(arg)) {
|
614
660
|
if (mpz_cmp_ui(mpq_denref(self_val), 1) != 0)
|
615
661
|
return Qfalse;
|
616
|
-
return (
|
662
|
+
return (mpz_cmp_si (mpq_numref (self_val), FIX2INT (arg)) == 0) ? Qtrue : Qfalse;
|
617
663
|
} else if (BIGNUM_P(arg)) {
|
618
664
|
if (mpz_cmp_ui(mpq_denref(self_val), 1) != 0)
|
619
665
|
return Qfalse;
|
@@ -630,6 +676,17 @@ VALUE r_gmpq_eq(VALUE self, VALUE arg)
|
|
630
676
|
}
|
631
677
|
}
|
632
678
|
|
679
|
+
/*
|
680
|
+
* Document-method: <=>
|
681
|
+
* call-seq:
|
682
|
+
* a <=> b
|
683
|
+
*
|
684
|
+
* Returns negative if _a_ is less than _b_.
|
685
|
+
*
|
686
|
+
* Returns 0 if _a_ is equal to _b_.
|
687
|
+
*
|
688
|
+
* Returns positive if _a_ is greater than _b_.
|
689
|
+
*/
|
633
690
|
VALUE r_gmpq_cmp(VALUE self, VALUE arg)
|
634
691
|
{
|
635
692
|
MP_RAT *self_val;
|
@@ -644,11 +701,53 @@ VALUE r_gmpq_cmp(VALUE self, VALUE arg)
|
|
644
701
|
return INT2FIX(-1);
|
645
702
|
}
|
646
703
|
|
704
|
+
/*
|
705
|
+
* Document-method: <
|
706
|
+
* call-seq:
|
707
|
+
* a < b
|
708
|
+
*
|
709
|
+
* Returns whether _a_ is strictly less than _b_.
|
710
|
+
*/
|
711
|
+
|
647
712
|
DEFUN_RAT_CMP(lt,<)
|
713
|
+
/*
|
714
|
+
* Document-method: <=
|
715
|
+
* call-seq:
|
716
|
+
* a <= b
|
717
|
+
*
|
718
|
+
* Returns whether _a_ is less than or equal to _b_.
|
719
|
+
*/
|
648
720
|
DEFUN_RAT_CMP(le,<=)
|
721
|
+
|
722
|
+
/*
|
723
|
+
* Document-method: >
|
724
|
+
* call-seq:
|
725
|
+
* a > b
|
726
|
+
*
|
727
|
+
* Returns whether _a_ is strictly greater than _b_.
|
728
|
+
*/
|
649
729
|
DEFUN_RAT_CMP(gt,>)
|
730
|
+
|
731
|
+
/*
|
732
|
+
* Document-method: >=
|
733
|
+
* call-seq:
|
734
|
+
* a >= b
|
735
|
+
*
|
736
|
+
* Returns whether _a_ is greater than or equal to _b_.
|
737
|
+
*/
|
650
738
|
DEFUN_RAT_CMP(ge,>=)
|
651
739
|
|
740
|
+
/*
|
741
|
+
* Document-method: cmpabs
|
742
|
+
* call-seq:
|
743
|
+
* a.cmpabs(b)
|
744
|
+
*
|
745
|
+
* Returns negative if _abs(a)_ is less than _abs(b)_.
|
746
|
+
*
|
747
|
+
* Returns 0 if _abs(a)_ is equal to _abs(b)_.
|
748
|
+
*
|
749
|
+
* Returns positive if _abs(a)_ is greater than _abs(b)_.
|
750
|
+
*/
|
652
751
|
static VALUE r_gmpq_cmpabs(VALUE self, VALUE arg)
|
653
752
|
{
|
654
753
|
MP_RAT *arg_val_q, *self_val;
|
@@ -714,9 +813,12 @@ static VALUE r_gmpq_cmpabs(VALUE self, VALUE arg)
|
|
714
813
|
} else {
|
715
814
|
typeerror (ZQFXB);
|
716
815
|
}
|
816
|
+
|
817
|
+
return Qnil; /* should never get here */
|
717
818
|
}
|
718
819
|
|
719
820
|
/*
|
821
|
+
* Document-method: sgn
|
720
822
|
* call-seq:
|
721
823
|
* p.sgn
|
722
824
|
*
|
@@ -730,14 +832,15 @@ VALUE r_gmpq_sgn(VALUE self)
|
|
730
832
|
}
|
731
833
|
|
732
834
|
/*
|
835
|
+
* Document-method: eql?
|
733
836
|
* call-seq:
|
734
837
|
* a.eql?(b)
|
735
838
|
*
|
736
839
|
* @since 0.5.47
|
737
840
|
*
|
738
|
-
* Returns
|
739
|
-
* and both be instances of GMP::Q
|
740
|
-
* b.class == GMP::Q
|
841
|
+
* Returns whether if _a_ is equal to _b_. _a_ and _b_ must be equal in
|
842
|
+
* cardinality, and both be instances of GMP::Q to return true. `a.eql?(b)` if
|
843
|
+
* and only if `b.class == GMP::Q`, and `a.hash == b.hash`.
|
741
844
|
*/
|
742
845
|
VALUE r_gmpq_eql(VALUE self, VALUE arg)
|
743
846
|
{
|
@@ -754,14 +857,16 @@ VALUE r_gmpq_eql(VALUE self, VALUE arg)
|
|
754
857
|
}
|
755
858
|
|
756
859
|
/*
|
860
|
+
* Document-method: hash
|
757
861
|
* call-seq:
|
758
862
|
* a.hash
|
759
863
|
*
|
760
864
|
* @since 0.5.47
|
761
865
|
*
|
762
|
-
* Returns the computed hash value of _a_. This method first converts _a_ into
|
763
|
-
* (base 10), then calls String#hash on the result, returning the hash
|
764
|
-
* if and only if b.class == GMP::Q
|
866
|
+
* Returns the computed hash value of _a_. This method first converts _a_ into
|
867
|
+
* a String (base 10), then calls String#hash on the result, returning the hash
|
868
|
+
* value. `a.eql?(b)` if and only if `b.class == GMP::Q`, and
|
869
|
+
* `a.hash == b.hash`.
|
765
870
|
*/
|
766
871
|
VALUE r_gmpq_hash(VALUE self)
|
767
872
|
{
|
@@ -774,7 +879,14 @@ VALUE r_gmpq_hash(VALUE self)
|
|
774
879
|
* Applying Integer Functions *
|
775
880
|
**********************************************************************/
|
776
881
|
|
777
|
-
|
882
|
+
/*
|
883
|
+
* Document-method: num
|
884
|
+
* call-seq:
|
885
|
+
* a.num
|
886
|
+
*
|
887
|
+
* Returns the numerator of _a_.
|
888
|
+
*/
|
889
|
+
VALUE r_gmpq_get_num(VALUE self)
|
778
890
|
{
|
779
891
|
MP_RAT *self_val;
|
780
892
|
MP_INT *res_val;
|
@@ -785,7 +897,15 @@ VALUE r_gmpq_num(VALUE self)
|
|
785
897
|
return res;
|
786
898
|
}
|
787
899
|
|
788
|
-
|
900
|
+
|
901
|
+
/*
|
902
|
+
* Document-method: den
|
903
|
+
* call-seq:
|
904
|
+
* a.den
|
905
|
+
*
|
906
|
+
* Returns the denominator of _a_.
|
907
|
+
*/
|
908
|
+
VALUE r_gmpq_get_den(VALUE self)
|
789
909
|
{
|
790
910
|
MP_RAT *self_val;
|
791
911
|
MP_INT *res_val;
|
@@ -818,7 +938,9 @@ void init_gmpq()
|
|
818
938
|
rb_define_method(cGMP_Q, "+", r_gmpq_add, 1);
|
819
939
|
rb_define_method(cGMP_Q, "-", r_gmpq_sub, 1);
|
820
940
|
rb_define_method(cGMP_Q, "*", r_gmpq_mul, 1);
|
941
|
+
/* TODO rb_define_method(cGMP_Q, "mul_2exp", r_gmpq_mul_2exp, 1); */
|
821
942
|
rb_define_method(cGMP_Q, "/", r_gmpq_div, 1);
|
943
|
+
/* TODO rb_define_method(cGMP_Q, "div_2exp", r_gmpq_div_2exp, 1); */
|
822
944
|
rb_define_method(cGMP_Q, "-@", r_gmpq_neg, 0);
|
823
945
|
rb_define_alias( cGMP_Q, "neg", "-@");
|
824
946
|
rb_define_method(cGMP_Q, "neg!", r_gmpq_neg_self, 0);
|
@@ -839,6 +961,12 @@ void init_gmpq()
|
|
839
961
|
|
840
962
|
rb_define_method(cGMP_Q, "eql?", r_gmpq_eql, 1);
|
841
963
|
rb_define_method(cGMP_Q, "hash", r_gmpq_hash, 0);
|
964
|
+
|
965
|
+
// Applying Integer Functions to Rationals
|
966
|
+
rb_define_method(cGMP_Q, "num", r_gmpq_get_num, 0);
|
967
|
+
rb_define_method(cGMP_Q, "den", r_gmpq_get_den, 0);
|
968
|
+
/* TODO rb_define_method(cGMP_Q, "num=", r_gmpq_set_num, 0); */
|
969
|
+
/* TODO rb_define_method(cGMP_Q, "den=", r_gmpq_set_den, 0); */
|
842
970
|
|
843
971
|
// _unsorted_
|
844
972
|
rb_define_method(cGMP_Q, "floor", r_gmpq_floor, 0);
|