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/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);
|