gmp 0.5.41 → 0.5.47
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +21 -0
- data/FEATURES.html +37 -38
- data/README.html +511 -0
- data/README.markdown +494 -0
- data/benchmark/divide +0 -0
- data/benchmark/gcd +0 -0
- data/benchmark/multiply +0 -0
- data/benchmark/multiply.fnl +0 -0
- data/benchmark/multiply.gc +0 -0
- data/benchmark/pi +0 -0
- data/benchmark/rsa +0 -0
- data/benchmark/runbench +0 -0
- data/benchmark/srb.sh +0 -0
- data/ext/gmp.c +0 -42
- data/ext/gmpf.c +64 -33
- data/ext/gmpq.c +88 -1
- data/ext/gmpz.c +151 -19
- data/ext/ruby_gmp.h +16 -10
- data/manual.pdf +0 -0
- data/manual.tex +50 -14
- data/test/gmp_tgcd.rb +18 -18
- data/test/mpfr_tcbrt.rb +1 -1
- data/test/mpfr_tconst_euler.rb +10 -7
- data/test/mpfr_tisnan.rb +1 -1
- data/test/mpfr_trec_sqrt.rb +1 -1
- data/test/mpfr_tsqrt.rb +1 -1
- data/test/tc_cmp.rb +7 -2
- data/test/tc_constants.rb +1 -1
- data/test/tc_division.rb +1 -1
- data/test/tc_f_arithmetics_coersion.rb +1 -1
- data/test/tc_f_precision.rb +1 -1
- data/test/tc_fib_fac_nextprime.rb +1 -1
- data/test/tc_floor_ceil_truncate.rb +1 -1
- data/test/tc_hashes.rb +26 -1
- data/test/tc_logical_roots.rb +1 -1
- data/test/tc_mpfr_constants.rb +1 -1
- data/test/tc_mpfr_functions.rb +1 -1
- data/test/tc_mpfr_random.rb +1 -1
- data/test/tc_mpfr_rounding.rb +3 -3
- data/test/tc_q.rb +1 -1
- data/test/tc_q_basic.rb +1 -1
- data/test/tc_random.rb +1 -1
- data/test/tc_sgn_neg_abs.rb +1 -1
- data/test/tc_swap.rb +1 -1
- data/test/tc_z.rb +34 -1
- data/test/tc_z_addmul.rb +1 -1
- data/test/tc_z_basic.rb +1 -1
- data/test/tc_z_exponentiation.rb +1 -1
- data/test/tc_z_functional_mappings.rb +42 -6
- data/test/tc_z_gcd_lcm_invert.rb +1 -1
- data/test/tc_z_jac_leg_rem.rb +1 -1
- data/test/tc_z_logic.rb +1 -1
- data/test/tc_z_shifts_last_bits.rb +1 -1
- data/test/tc_z_submul.rb +1 -1
- data/test/tc_z_to_dis.rb +1 -1
- data/test/tc_zerodivisionexceptions.rb +1 -1
- data/test/test_helper.rb +2 -1
- data/test/unit_tests.rb +1 -1
- metadata +70 -89
- data/README.rdoc +0 -450
data/benchmark/divide
CHANGED
File without changes
|
data/benchmark/gcd
CHANGED
File without changes
|
data/benchmark/multiply
CHANGED
File without changes
|
data/benchmark/multiply.fnl
CHANGED
File without changes
|
data/benchmark/multiply.gc
CHANGED
File without changes
|
data/benchmark/pi
CHANGED
File without changes
|
data/benchmark/rsa
CHANGED
File without changes
|
data/benchmark/runbench
CHANGED
File without changes
|
data/benchmark/srb.sh
CHANGED
File without changes
|
data/ext/gmp.c
CHANGED
@@ -20,48 +20,6 @@ void r_gmpf_free(void *ptr) { mpf_clear (ptr); free (ptr); }
|
|
20
20
|
#endif
|
21
21
|
void r_gmprandstate_free(void *ptr) { gmp_randclear (ptr); free (ptr); }
|
22
22
|
|
23
|
-
static void mpq_str_set(MP_RAT *ROP, char *str)
|
24
|
-
{
|
25
|
-
int i=0;
|
26
|
-
|
27
|
-
while (str[i] && str[i] != '/')
|
28
|
-
i++;
|
29
|
-
|
30
|
-
if (str[i])
|
31
|
-
{
|
32
|
-
str[i] = 0; /* You didn't see that :) */
|
33
|
-
mpz_set_str (mpq_numref(ROP), str, 0);
|
34
|
-
str[i] = '/';
|
35
|
-
mpz_set_str (mpq_denref(ROP), str+i+1, 0);
|
36
|
-
} else {
|
37
|
-
mpz_set_str (mpq_numref(ROP), str, 0);
|
38
|
-
mpz_set_ui (mpq_denref(ROP), 1);
|
39
|
-
}
|
40
|
-
mpq_canonicalize (ROP);
|
41
|
-
}
|
42
|
-
|
43
|
-
static VALUE r_gmpq_initialize(int argc, VALUE *argv, VALUE self)
|
44
|
-
{
|
45
|
-
MP_RAT *self_val, *arg_val;
|
46
|
-
|
47
|
-
if (argc != 0) {
|
48
|
-
mpq_get_struct(self, self_val);
|
49
|
-
if (argc == 1 && GMPQ_P(argv[0])) {
|
50
|
-
mpq_get_struct(argv[0], arg_val);
|
51
|
-
mpq_set (self_val, arg_val);
|
52
|
-
} else if (argc == 1 && STRING_P(argv[0])) {
|
53
|
-
mpq_str_set (self_val, StringValuePtr(argv[0]));
|
54
|
-
} else {
|
55
|
-
mpz_set_value (mpq_numref(self_val), argv[0]);
|
56
|
-
if (argc == 2) {
|
57
|
-
mpz_set_value (mpq_denref(self_val), argv[1]);
|
58
|
-
mpq_canonicalize(self_val);
|
59
|
-
}
|
60
|
-
}
|
61
|
-
}
|
62
|
-
return Qnil;
|
63
|
-
}
|
64
|
-
|
65
23
|
static VALUE r_gmpz_coerce(VALUE self, VALUE arg)
|
66
24
|
{
|
67
25
|
return rb_assoc_new(r_gmpzsg_new(1, &arg, cGMP_Z), self);
|
data/ext/gmpf.c
CHANGED
@@ -50,9 +50,9 @@ static VALUE r_gmpf_cmp_##name(VALUE self, VALUE arg) \
|
|
50
50
|
|
51
51
|
/*
|
52
52
|
* call-seq:
|
53
|
-
* GMP::
|
53
|
+
* GMP::F.new(arg)
|
54
54
|
*
|
55
|
-
* Creates a new GMP::
|
55
|
+
* Creates a new GMP::F float, with arg as its value, converting where
|
56
56
|
* necessary.
|
57
57
|
*/
|
58
58
|
VALUE r_gmpfsg_new(int argc, VALUE *argv, VALUE klass)
|
@@ -114,7 +114,7 @@ VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
|
|
114
114
|
mpfr_init (self_val);
|
115
115
|
else
|
116
116
|
mpfr_init2 (self_val, prec);
|
117
|
-
|
117
|
+
|
118
118
|
if (STRING_P(argv[0])) {
|
119
119
|
if (argc >= 3) {
|
120
120
|
if (FIXNUM_P(argv[2])) {
|
@@ -130,7 +130,7 @@ VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
|
|
130
130
|
if (argc == 4) {
|
131
131
|
// FIGURE IT OUT. ACCEPT A ROUNDING MODE!
|
132
132
|
}
|
133
|
-
|
133
|
+
|
134
134
|
mpf_set_value2 (self_val, arg, base);
|
135
135
|
return Qnil;
|
136
136
|
}
|
@@ -215,7 +215,7 @@ void mpf_set_value2(MP_FLOAT *self_val, VALUE arg, int base)
|
|
215
215
|
int result;
|
216
216
|
|
217
217
|
result = mpfr_set_str(self_val, StringValuePtr(arg), base, __gmp_default_rounding_mode);
|
218
|
-
|
218
|
+
|
219
219
|
if (result == -1) {
|
220
220
|
rb_raise(rb_eRuntimeError, "Badly formatted string");
|
221
221
|
}
|
@@ -268,10 +268,10 @@ VALUE r_gmpf_to_s(VALUE self)
|
|
268
268
|
mp_exp_t exponent;
|
269
269
|
|
270
270
|
mpf_get_struct(self, self_val);
|
271
|
-
|
271
|
+
|
272
272
|
//mpfr_sprintf(str, "%Rf", self_val);
|
273
273
|
//res = rb_str_new2(str);
|
274
|
-
|
274
|
+
|
275
275
|
str = mpfr_get_str(NULL, &exponent, 10, 0, self_val, __gmp_default_rounding_mode);
|
276
276
|
if ((strcmp(str, "NaN") == 0) ||
|
277
277
|
(strcmp(str, "Inf") == 0) ||
|
@@ -587,7 +587,7 @@ VALUE r_gmpf_pow(VALUE self, VALUE arg)
|
|
587
587
|
{
|
588
588
|
MP_FLOAT *self_val, *res_val;
|
589
589
|
VALUE res;
|
590
|
-
|
590
|
+
|
591
591
|
//unsigned long prec;
|
592
592
|
mpfr_prec_t prec;
|
593
593
|
|
@@ -685,11 +685,11 @@ VALUE r_gmpf_div(VALUE self, VALUE arg)
|
|
685
685
|
mp_rnd_t rnd_mode_value;
|
686
686
|
MP_INT *arg_val_z;
|
687
687
|
VALUE res;
|
688
|
-
|
688
|
+
|
689
689
|
rb_scan_args (argc, argv, "12", &arg, &rnd_mode, &res_prec);
|
690
690
|
|
691
691
|
mpf_get_struct_prec (self, self_val, prec);
|
692
|
-
|
692
|
+
|
693
693
|
if (NIL_P (rnd_mode)) { rnd_mode_value = __gmp_default_rounding_mode; }
|
694
694
|
else { rnd_mode_value = r_get_rounding_mode(rnd_mode); }
|
695
695
|
if (NIL_P (res_prec)) { res_prec_value = prec; }
|
@@ -1107,7 +1107,7 @@ VALUE r_gmpfsg_set_default_rounding_mode(VALUE klass, VALUE arg)
|
|
1107
1107
|
} else {
|
1108
1108
|
rb_raise(rb_eTypeError, "rounding mode must be one of the rounding mode constants.");
|
1109
1109
|
}
|
1110
|
-
|
1110
|
+
|
1111
1111
|
switch (FIX2INT(mode)) {
|
1112
1112
|
case 0:
|
1113
1113
|
mpfr_set_default_rounding_mode (GMP_RNDN); break;
|
@@ -1122,17 +1122,17 @@ VALUE r_gmpfsg_set_default_rounding_mode(VALUE klass, VALUE arg)
|
|
1122
1122
|
mpfr_set_default_rounding_mode (MPFR_RNDA); break;
|
1123
1123
|
#endif
|
1124
1124
|
}
|
1125
|
-
|
1125
|
+
|
1126
1126
|
return Qnil;
|
1127
1127
|
}
|
1128
|
-
|
1128
|
+
|
1129
1129
|
VALUE r_gmpf_can_round(VALUE self, VALUE err, VALUE rnd1, VALUE rnd2, VALUE prec)
|
1130
1130
|
{
|
1131
1131
|
MP_FLOAT *self_val;
|
1132
1132
|
mp_exp_t err_val;
|
1133
1133
|
mpfr_rnd_t rnd1_val, rnd2_val;
|
1134
1134
|
mpfr_prec_t prec_val;
|
1135
|
-
|
1135
|
+
|
1136
1136
|
mpf_get_struct(self, self_val);
|
1137
1137
|
if (FIXNUM_P(err)) {
|
1138
1138
|
err_val = FIX2INT(err);
|
@@ -1142,7 +1142,7 @@ VALUE r_gmpf_can_round(VALUE self, VALUE err, VALUE rnd1, VALUE rnd2, VALUE prec
|
|
1142
1142
|
rnd1_val = r_get_rounding_mode(rnd1);
|
1143
1143
|
rnd2_val = r_get_rounding_mode(rnd2);
|
1144
1144
|
prec_val = FIX2INT (prec);
|
1145
|
-
|
1145
|
+
|
1146
1146
|
if (mpfr_can_round (self_val, err_val, rnd1_val, rnd2_val, prec_val))
|
1147
1147
|
return Qtrue;
|
1148
1148
|
else
|
@@ -1152,6 +1152,23 @@ VALUE r_gmpf_can_round(VALUE self, VALUE err, VALUE rnd1, VALUE rnd2, VALUE prec
|
|
1152
1152
|
#endif
|
1153
1153
|
|
1154
1154
|
|
1155
|
+
/**********************************************************************
|
1156
|
+
* Rounding Related Functions *
|
1157
|
+
**********************************************************************/
|
1158
|
+
|
1159
|
+
VALUE r_gmpfsg_mpfr_buildopt_tls_p(VALUE klass)
|
1160
|
+
{
|
1161
|
+
(void)klass;
|
1162
|
+
return INT2FIX (mpfr_buildopt_tls_p());
|
1163
|
+
}
|
1164
|
+
|
1165
|
+
VALUE r_gmpfsg_mpfr_buildopt_decimal_p(VALUE klass)
|
1166
|
+
{
|
1167
|
+
(void)klass;
|
1168
|
+
return INT2FIX (mpfr_buildopt_decimal_p());
|
1169
|
+
}
|
1170
|
+
|
1171
|
+
|
1155
1172
|
/**********************************************************************
|
1156
1173
|
* _unsorted_ *
|
1157
1174
|
**********************************************************************/
|
@@ -1192,22 +1209,22 @@ void init_gmpf()
|
|
1192
1209
|
{
|
1193
1210
|
mGMP = rb_define_module("GMP");
|
1194
1211
|
rb_define_module_function(mGMP, "F", r_gmpmod_f, -1);
|
1195
|
-
|
1212
|
+
|
1196
1213
|
cGMP_F = rb_define_class_under (mGMP, "F", rb_cNumeric);
|
1197
|
-
|
1198
|
-
|
1214
|
+
|
1215
|
+
|
1199
1216
|
// Initializing, Assigning Floats
|
1200
1217
|
rb_define_singleton_method(cGMP_F, "new", r_gmpfsg_new, -1);
|
1201
1218
|
rb_define_method(cGMP_F, "initialize", r_gmpf_initialize, -1);
|
1202
1219
|
rb_define_method(cGMP_F, "prec", r_gmpf_get_prec, 0);
|
1203
1220
|
rb_define_method(cGMP_F, "prec=", r_gmpf_set_prec, 1);
|
1204
1221
|
rb_define_method(cGMP_F, "prec_raw=", r_gmpf_set_prec_raw, 1);
|
1205
|
-
|
1222
|
+
|
1206
1223
|
// Converting Floats
|
1207
1224
|
rb_define_method(cGMP_F, "to_s", r_gmpf_to_s, 0);
|
1208
1225
|
rb_define_method(cGMP_F, "to_d", r_gmpf_to_d, 0);
|
1209
1226
|
rb_define_alias(cGMP_F, "to_f", "to_d");
|
1210
|
-
|
1227
|
+
|
1211
1228
|
// Float Arithmetic
|
1212
1229
|
rb_define_method(cGMP_F, "-", r_gmpf_sub, 1);
|
1213
1230
|
rb_define_method(cGMP_F, "/", r_gmpf_div, 1);
|
@@ -1226,7 +1243,7 @@ void init_gmpf()
|
|
1226
1243
|
rb_define_method(cGMP_F, "neg!", r_gmpf_neg_self, 0);
|
1227
1244
|
rb_define_method(cGMP_F, "abs", r_gmpf_abs, 0);
|
1228
1245
|
rb_define_method(cGMP_F, "abs!", r_gmpf_abs_self, 0);
|
1229
|
-
|
1246
|
+
|
1230
1247
|
// Float Comparison
|
1231
1248
|
rb_define_method(cGMP_F, "<=>", r_gmpf_cmp, 1);
|
1232
1249
|
rb_define_method(cGMP_F, ">", r_gmpf_cmp_gt, 1);
|
@@ -1235,20 +1252,18 @@ void init_gmpf()
|
|
1235
1252
|
rb_define_method(cGMP_F, "<=", r_gmpf_cmp_le, 1);
|
1236
1253
|
rb_define_method(cGMP_F, "==", r_gmpf_eq, 1);
|
1237
1254
|
rb_define_method(cGMP_F, "sgn", r_gmpf_sgn, 0);
|
1238
|
-
|
1255
|
+
|
1239
1256
|
// Miscellaneous Functions
|
1240
1257
|
rb_define_method(cGMP_F, "ceil", r_gmpf_ceil, 0);
|
1241
1258
|
rb_define_method(cGMP_F, "ceil!", r_gmpf_ceil_self, 0);
|
1242
1259
|
rb_define_method(cGMP_F, "floor", r_gmpf_floor, 0);
|
1243
1260
|
rb_define_method(cGMP_F, "floor!", r_gmpf_floor_self, 0);rb_define_method(cGMP_F, "trunc", r_gmpf_trunc, 0);
|
1244
1261
|
rb_define_method(cGMP_F, "trunc!", r_gmpf_trunc_self, 0);
|
1245
|
-
|
1246
|
-
|
1262
|
+
|
1263
|
+
|
1247
1264
|
#ifdef MPFR
|
1248
1265
|
/* To implement; new in MPFR 3.0.0:
|
1249
1266
|
*
|
1250
|
-
* mpfr_buildopt_tls_p
|
1251
|
-
* mpfr_buildopt_decimal_p
|
1252
1267
|
* mpfr_set_zero
|
1253
1268
|
* mpfr_ai
|
1254
1269
|
* mpfr_set_flt
|
@@ -1256,6 +1271,16 @@ void init_gmpf()
|
|
1256
1271
|
* mpfr_urandom
|
1257
1272
|
* mpfr_set_z_2exp
|
1258
1273
|
*/
|
1274
|
+
|
1275
|
+
/* To implement; new in MPFR 3.1.0:
|
1276
|
+
*
|
1277
|
+
* mpfr_buildopt_gmpinternals_p
|
1278
|
+
* mpfr_buildopt_tune_case
|
1279
|
+
* mpfr_frexp
|
1280
|
+
* mpfr_grandom
|
1281
|
+
* mpfr_z_sub
|
1282
|
+
*/
|
1283
|
+
|
1259
1284
|
// Basic Arithmetic Functions
|
1260
1285
|
rb_define_method(cGMP_F, "sqrt", r_gmpfr_sqrt, -1);
|
1261
1286
|
rb_define_method(cGMP_F, "rec_sqrt", r_gmpfr_rec_sqrt, -1);
|
@@ -1266,9 +1291,9 @@ void init_gmpf()
|
|
1266
1291
|
// "dim", r_gmpfr_dim
|
1267
1292
|
// "mul_2", r_gmpfr_mul_2
|
1268
1293
|
// "div_2", r_gmpfr_div_2
|
1269
|
-
|
1294
|
+
|
1270
1295
|
//rb_define_method(cGMP_F, "**", r_gmpfr_pow, 1);
|
1271
|
-
|
1296
|
+
|
1272
1297
|
// Comparison Functions
|
1273
1298
|
rb_define_method(cGMP_F, "nan?", r_gmpfr_nan_p, 0);
|
1274
1299
|
rb_define_method(cGMP_F, "infinite?", r_gmpfr_inf_p, 0);
|
@@ -1281,7 +1306,7 @@ void init_gmpf()
|
|
1281
1306
|
//"sgn", r_gmpfr_sgn
|
1282
1307
|
//"lessgreater", r_gmpfr_lessgreater_p
|
1283
1308
|
//"unordered", r_gmpfr_unordered_p
|
1284
|
-
|
1309
|
+
|
1285
1310
|
// Special Functions
|
1286
1311
|
rb_define_method(cGMP_F, "log", r_gmpfr_log, -1);
|
1287
1312
|
rb_define_method(cGMP_F, "log2", r_gmpfr_log2, -1);
|
@@ -1310,7 +1335,7 @@ void init_gmpf()
|
|
1310
1335
|
rb_define_method(cGMP_F, "acosh", r_gmpfr_acosh, -1);
|
1311
1336
|
rb_define_method(cGMP_F, "asinh", r_gmpfr_asinh, -1);
|
1312
1337
|
rb_define_method(cGMP_F, "atanh", r_gmpfr_atanh, -1);
|
1313
|
-
|
1338
|
+
|
1314
1339
|
// "fac", r_gmpfr_fac
|
1315
1340
|
|
1316
1341
|
rb_define_method(cGMP_F, "log1p", r_gmpfr_log1p, -1);
|
@@ -1338,7 +1363,7 @@ void init_gmpf()
|
|
1338
1363
|
rb_define_method(cGMP_F, "agm", r_gmpfr_agm, -1);
|
1339
1364
|
rb_define_method(cGMP_F, "hypot", r_gmpfr_hypot, -1);
|
1340
1365
|
// "ai", r_gmpfr_ai !! 3.0.0
|
1341
|
-
|
1366
|
+
|
1342
1367
|
rb_define_singleton_method(cGMP_F, "const_log2", r_gmpfrsg_const_log2, -1);
|
1343
1368
|
rb_define_singleton_method(cGMP_F, "const_pi", r_gmpfrsg_const_pi, -1);
|
1344
1369
|
rb_define_singleton_method(cGMP_F, "const_euler", r_gmpfrsg_const_euler, -1);
|
@@ -1346,12 +1371,18 @@ void init_gmpf()
|
|
1346
1371
|
|
1347
1372
|
// Integer and Remainder Related Functions
|
1348
1373
|
// "integer?", r_gmpfr_integer_p
|
1349
|
-
|
1374
|
+
|
1350
1375
|
// Rounding Related Functions
|
1351
1376
|
rb_define_singleton_method (cGMP_F, "default_rounding_mode", r_gmpfsg_get_default_rounding_mode, 0);
|
1352
1377
|
rb_define_singleton_method (cGMP_F, "default_rounding_mode=", r_gmpfsg_set_default_rounding_mode, 1);
|
1353
1378
|
rb_define_method(cGMP_F, "can_round?", r_gmpf_can_round, 4);
|
1379
|
+
|
1380
|
+
// Miscellaneous Functions
|
1381
|
+
#if MPFR_VERSION_MAJOR > 2
|
1382
|
+
rb_define_singleton_method (cGMP_F, "mpfr_buildopt_decimal_p", r_gmpfsg_mpfr_buildopt_decimal_p, 0);
|
1383
|
+
rb_define_singleton_method (cGMP_F, "mpfr_buildopt_tls_p", r_gmpfsg_mpfr_buildopt_tls_p, 0);
|
1384
|
+
#endif /* MPFR > 2 */
|
1354
1385
|
#endif /* MPFR */
|
1355
|
-
|
1386
|
+
|
1356
1387
|
// _unsorted_
|
1357
1388
|
}
|
data/ext/gmpq.c
CHANGED
@@ -69,6 +69,7 @@ static VALUE r_gmpq_##fname##_self(VALUE self) \
|
|
69
69
|
/*
|
70
70
|
* call-seq:
|
71
71
|
* GMP::Q.new(arg)
|
72
|
+
* GMP::Q.new(num,den)
|
72
73
|
*
|
73
74
|
* Creates a new GMP::Q rational, with _arg_ as its value, converting where
|
74
75
|
* necessary.
|
@@ -86,10 +87,52 @@ VALUE r_gmpqsg_new(int argc, VALUE *argv, VALUE klass)
|
|
86
87
|
mpq_make_struct (res, res_val);
|
87
88
|
mpq_init (res_val);
|
88
89
|
rb_obj_call_init(res, argc, argv);
|
89
|
-
|
90
|
+
|
90
91
|
return res;
|
91
92
|
}
|
92
93
|
|
94
|
+
static void mpq_str_set(MP_RAT *ROP, char *str)
|
95
|
+
{
|
96
|
+
int i=0;
|
97
|
+
|
98
|
+
while (str[i] && str[i] != '/')
|
99
|
+
i++;
|
100
|
+
|
101
|
+
if (str[i])
|
102
|
+
{
|
103
|
+
str[i] = 0; /* You didn't see that :) */
|
104
|
+
mpz_set_str (mpq_numref(ROP), str, 0);
|
105
|
+
str[i] = '/';
|
106
|
+
mpz_set_str (mpq_denref(ROP), str+i+1, 0);
|
107
|
+
} else {
|
108
|
+
mpz_set_str (mpq_numref(ROP), str, 0);
|
109
|
+
mpz_set_ui (mpq_denref(ROP), 1);
|
110
|
+
}
|
111
|
+
mpq_canonicalize (ROP);
|
112
|
+
}
|
113
|
+
|
114
|
+
VALUE r_gmpq_initialize(int argc, VALUE *argv, VALUE self)
|
115
|
+
{
|
116
|
+
MP_RAT *self_val, *arg_val;
|
117
|
+
|
118
|
+
if (argc != 0) {
|
119
|
+
mpq_get_struct(self, self_val);
|
120
|
+
if (argc == 1 && GMPQ_P(argv[0])) {
|
121
|
+
mpq_get_struct(argv[0], arg_val);
|
122
|
+
mpq_set (self_val, arg_val);
|
123
|
+
} else if (argc == 1 && STRING_P(argv[0])) {
|
124
|
+
mpq_str_set (self_val, StringValuePtr(argv[0]));
|
125
|
+
} else {
|
126
|
+
mpz_set_value (mpq_numref(self_val), argv[0], 0); // are these segfaulting?
|
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?
|
131
|
+
}
|
132
|
+
}
|
133
|
+
return Qnil;
|
134
|
+
}
|
135
|
+
|
93
136
|
/*
|
94
137
|
* call-seq:
|
95
138
|
* GMP::Q(arg)
|
@@ -686,6 +729,47 @@ VALUE r_gmpq_sgn(VALUE self)
|
|
686
729
|
return INT2FIX(mpq_sgn(self_val));
|
687
730
|
}
|
688
731
|
|
732
|
+
/*
|
733
|
+
* call-seq:
|
734
|
+
* a.eql?(b)
|
735
|
+
*
|
736
|
+
* @since 0.5.47
|
737
|
+
*
|
738
|
+
* Returns true if _a_ is equal to _b_. _a_ and _b_ must then be equal in cardinality,
|
739
|
+
* and both be instances of GMP::Q. Otherwise, returns false. a.eql?(b) if and only if
|
740
|
+
* b.class == GMP::Q, and a.hash == b.hash.
|
741
|
+
*/
|
742
|
+
VALUE r_gmpq_eql(VALUE self, VALUE arg)
|
743
|
+
{
|
744
|
+
MP_RAT *self_val, *arg_val;
|
745
|
+
mpq_get_struct(self,self_val);
|
746
|
+
|
747
|
+
if (GMPQ_P(arg)) {
|
748
|
+
mpq_get_struct(arg, arg_val);
|
749
|
+
return (mpq_cmp (self_val, arg_val) == 0) ? Qtrue : Qfalse;
|
750
|
+
}
|
751
|
+
else {
|
752
|
+
return Qfalse;
|
753
|
+
}
|
754
|
+
}
|
755
|
+
|
756
|
+
/*
|
757
|
+
* call-seq:
|
758
|
+
* a.hash
|
759
|
+
*
|
760
|
+
* @since 0.5.47
|
761
|
+
*
|
762
|
+
* Returns the computed hash value of _a_. This method first converts _a_ into a String
|
763
|
+
* (base 10), then calls String#hash on the result, returning the hash value. a.eql?(b)
|
764
|
+
* if and only if b.class == GMP::Q, and a.hash == b.hash.
|
765
|
+
*/
|
766
|
+
VALUE r_gmpq_hash(VALUE self)
|
767
|
+
{
|
768
|
+
ID to_s_sym = rb_intern("to_s");
|
769
|
+
ID hash_sym = rb_intern("hash");
|
770
|
+
return rb_funcall(rb_funcall(self, to_s_sym, 0), hash_sym, 0);
|
771
|
+
}
|
772
|
+
|
689
773
|
/**********************************************************************
|
690
774
|
* Applying Integer Functions *
|
691
775
|
**********************************************************************/
|
@@ -752,6 +836,9 @@ void init_gmpq()
|
|
752
836
|
rb_define_method(cGMP_Q, "sgn", r_gmpq_sgn, 0);
|
753
837
|
rb_define_method(cGMP_Q, "cmpabs", r_gmpq_cmpabs, 1);
|
754
838
|
|
839
|
+
rb_define_method(cGMP_Q, "eql?", r_gmpq_eql, 1);
|
840
|
+
rb_define_method(cGMP_Q, "hash", r_gmpq_hash, 0);
|
841
|
+
|
755
842
|
// _unsorted_
|
756
843
|
rb_define_method(cGMP_Q, "floor", r_gmpq_floor, 0);
|
757
844
|
rb_define_method(cGMP_Q, "ceil", r_gmpq_ceil, 0);
|