srawlins-gmp 0.1.1
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.
- data/CHANGELOG +23 -0
- data/INSTALL +4 -0
- data/README.rdoc +248 -0
- data/ext/extconf.rb +30 -0
- data/ext/gmp.c +561 -0
- data/ext/gmpf.h +442 -0
- data/ext/gmpq.h +486 -0
- data/ext/gmpz.h +833 -0
- data/ext/takeover.h +36 -0
- data/test/README +41 -0
- data/test/tc_cmp.rb +74 -0
- data/test/tc_q.rb +27 -0
- data/test/tc_q_basic.rb +41 -0
- data/test/tc_z.rb +59 -0
- data/test/tc_z_basic.rb +35 -0
- data/test/tc_z_exponentiation.rb +22 -0
- data/test/tc_z_logic.rb +54 -0
- data/test/test_helper.rb +2 -0
- data/test/unit_tests.rb +75 -0
- metadata +81 -0
data/ext/gmpf.h
ADDED
@@ -0,0 +1,442 @@
|
|
1
|
+
static VALUE r_gmpf_to_d(VALUE self)
|
2
|
+
{
|
3
|
+
MP_FLOAT *self_val;
|
4
|
+
mpf_get_struct (self, self_val);
|
5
|
+
|
6
|
+
return rb_float_new(mpf_get_d(self_val));
|
7
|
+
}
|
8
|
+
|
9
|
+
static VALUE r_gmpf_to_s(VALUE self)
|
10
|
+
{
|
11
|
+
MP_FLOAT *self_val;
|
12
|
+
char *str, *str2;
|
13
|
+
VALUE res;
|
14
|
+
mp_exp_t exponent;
|
15
|
+
|
16
|
+
mpf_get_struct(self, self_val);
|
17
|
+
|
18
|
+
str = mpf_get_str(NULL, &exponent, 10, 0, self_val);
|
19
|
+
if ((strcmp (str, "NaN") == 0) ||
|
20
|
+
(strcmp (str, "Inf") == 0) ||
|
21
|
+
(strcmp (str, "-Inf") == 0))
|
22
|
+
{
|
23
|
+
res = rb_str_new2(str);
|
24
|
+
}
|
25
|
+
else
|
26
|
+
{
|
27
|
+
if (str[0] == '-')
|
28
|
+
__gmp_asprintf (&str2, "-0.%se%+ld", str+1, exponent);
|
29
|
+
else
|
30
|
+
__gmp_asprintf (&str2, "0.%se%+ld", str, exponent);
|
31
|
+
res = rb_str_new2(str2);
|
32
|
+
free (str2);
|
33
|
+
}
|
34
|
+
free (str);
|
35
|
+
return res;
|
36
|
+
}
|
37
|
+
|
38
|
+
static VALUE r_gmpf_add(VALUE self, VALUE arg)
|
39
|
+
{
|
40
|
+
MP_FLOAT *self_val, *res_val, *arg_val_f;
|
41
|
+
MP_RAT *arg_val_q;
|
42
|
+
MP_INT *arg_val_z;
|
43
|
+
VALUE res;
|
44
|
+
unsigned long prec;
|
45
|
+
|
46
|
+
mpf_get_struct_prec (self, self_val, prec);
|
47
|
+
|
48
|
+
if (GMPF_P(arg)) {
|
49
|
+
mpf_get_struct (arg, arg_val_f);
|
50
|
+
prec_max(prec, arg_val_f);
|
51
|
+
mpf_make_struct_init(res, res_val, prec);
|
52
|
+
mpf_add(res_val, self_val, arg_val_f);
|
53
|
+
} else if (GMPQ_P(arg)) {
|
54
|
+
mpq_get_struct (arg, arg_val_q);
|
55
|
+
mpf_make_struct_init(res, res_val, prec);
|
56
|
+
mpf_set_q (res_val, arg_val_q);
|
57
|
+
mpf_add (res_val, res_val, self_val);
|
58
|
+
} else if (GMPZ_P(arg)) {
|
59
|
+
mpz_get_struct (arg, arg_val_z);
|
60
|
+
mpf_make_struct_init(res, res_val, prec);
|
61
|
+
mpf_set_z (res_val, arg_val_z);
|
62
|
+
mpf_add (res_val, res_val, self_val);
|
63
|
+
} else if (FLOAT_P(arg)) {
|
64
|
+
mpf_make_struct_init(res, res_val, prec);
|
65
|
+
mpf_set_d (res_val, FLT2DBL(arg));
|
66
|
+
mpf_add (res_val, res_val, self_val);
|
67
|
+
} else if (FIXNUM_P(arg)) { // _ui with sign control instead ?
|
68
|
+
mpf_make_struct_init(res, res_val, prec);
|
69
|
+
mpf_set_si (res_val, FIX2INT(arg));
|
70
|
+
mpf_add (res_val, res_val, self_val);
|
71
|
+
} else if (BIGNUM_P(arg)) {
|
72
|
+
mpz_temp_from_bignum(arg_val_z, arg);
|
73
|
+
mpf_make_struct_init(res, res_val, prec);
|
74
|
+
mpf_set_z (res_val, arg_val_z);
|
75
|
+
mpf_add (res_val, res_val, self_val);
|
76
|
+
mpz_temp_free(arg_val_z);
|
77
|
+
} else {
|
78
|
+
typeerror(ZQFXBD);
|
79
|
+
}
|
80
|
+
|
81
|
+
return res;
|
82
|
+
}
|
83
|
+
|
84
|
+
static VALUE r_gmpf_sub(VALUE self, VALUE arg)
|
85
|
+
{
|
86
|
+
MP_FLOAT *self_val, *res_val, *arg_val_f;
|
87
|
+
MP_RAT *arg_val_q;
|
88
|
+
MP_INT *arg_val_z;
|
89
|
+
VALUE res;
|
90
|
+
unsigned long prec;
|
91
|
+
|
92
|
+
mpf_get_struct_prec (self, self_val, prec);
|
93
|
+
|
94
|
+
if (GMPF_P(arg)) {
|
95
|
+
mpf_get_struct (arg, arg_val_f);
|
96
|
+
prec_max(prec, arg_val_f);
|
97
|
+
mpf_make_struct_init(res, res_val, prec);
|
98
|
+
mpf_sub(res_val, self_val, arg_val_f);
|
99
|
+
} else if (GMPQ_P(arg)) {
|
100
|
+
mpq_get_struct (arg, arg_val_q);
|
101
|
+
mpf_make_struct_init(res, res_val, prec);
|
102
|
+
mpf_set_q (res_val, arg_val_q);
|
103
|
+
mpf_sub (res_val, self_val, res_val);
|
104
|
+
} else if (GMPZ_P(arg)) {
|
105
|
+
mpz_get_struct (arg, arg_val_z);
|
106
|
+
mpf_make_struct_init(res, res_val, prec);
|
107
|
+
mpf_set_z (res_val, arg_val_z);
|
108
|
+
mpf_sub (res_val, self_val, res_val);
|
109
|
+
} else if (FLOAT_P(arg)) {
|
110
|
+
mpf_make_struct_init(res, res_val, prec);
|
111
|
+
mpf_set_d (res_val, FLT2DBL(arg));
|
112
|
+
mpf_sub (res_val, self_val, res_val);
|
113
|
+
} else if (FIXNUM_P(arg)) { // _ui with sign control instead ?
|
114
|
+
mpf_make_struct_init(res, res_val, prec);
|
115
|
+
mpf_set_si (res_val, FIX2INT(arg));
|
116
|
+
mpf_sub (res_val, self_val, res_val);
|
117
|
+
} else if (BIGNUM_P(arg)) {
|
118
|
+
mpz_temp_from_bignum(arg_val_z, arg);
|
119
|
+
mpf_make_struct_init(res, res_val, prec);
|
120
|
+
mpf_set_z (res_val, arg_val_z);
|
121
|
+
mpf_sub (res_val, res_val, self_val);
|
122
|
+
mpz_temp_free(arg_val_z);
|
123
|
+
} else {
|
124
|
+
typeerror(ZQFXBD);
|
125
|
+
}
|
126
|
+
|
127
|
+
return res;
|
128
|
+
}
|
129
|
+
|
130
|
+
static VALUE r_gmpf_mul(VALUE self, VALUE arg)
|
131
|
+
{
|
132
|
+
MP_FLOAT *self_val, *res_val, *arg_val_f;
|
133
|
+
MP_RAT *arg_val_q;
|
134
|
+
MP_INT *arg_val_z;
|
135
|
+
VALUE res;
|
136
|
+
unsigned long prec;
|
137
|
+
|
138
|
+
mpf_get_struct_prec (self, self_val, prec);
|
139
|
+
|
140
|
+
if (GMPF_P(arg)) {
|
141
|
+
mpf_get_struct (arg, arg_val_f);
|
142
|
+
prec_max(prec, arg_val_f);
|
143
|
+
mpf_make_struct_init(res, res_val, prec);
|
144
|
+
mpf_mul(res_val, self_val, arg_val_f);
|
145
|
+
} else if (GMPQ_P(arg)) {
|
146
|
+
mpq_get_struct (arg, arg_val_q);
|
147
|
+
mpf_make_struct_init(res, res_val, prec);
|
148
|
+
mpf_set_q (res_val, arg_val_q);
|
149
|
+
mpf_mul (res_val, self_val, res_val);
|
150
|
+
} else if (GMPZ_P(arg)) {
|
151
|
+
mpz_get_struct (arg, arg_val_z);
|
152
|
+
mpf_make_struct_init(res, res_val, prec);
|
153
|
+
mpf_set_z (res_val, arg_val_z);
|
154
|
+
mpf_mul (res_val, self_val, res_val);
|
155
|
+
} else if (FLOAT_P(arg)) {
|
156
|
+
mpf_make_struct_init(res, res_val, prec);
|
157
|
+
mpf_set_d (res_val, FLT2DBL(arg));
|
158
|
+
mpf_mul (res_val, self_val, res_val);
|
159
|
+
} else if (FIXNUM_P(arg)) { // _ui with sign control instead ?
|
160
|
+
mpf_make_struct_init(res, res_val, prec);
|
161
|
+
mpf_set_si (res_val, FIX2INT(arg));
|
162
|
+
mpf_mul (res_val, self_val, res_val);
|
163
|
+
} else if (BIGNUM_P(arg)) {
|
164
|
+
mpz_temp_from_bignum(arg_val_z, arg);
|
165
|
+
mpf_make_struct_init(res, res_val, prec);
|
166
|
+
mpf_set_z (res_val, arg_val_z);
|
167
|
+
mpf_mul (res_val, res_val, self_val);
|
168
|
+
mpz_temp_free(arg_val_z);
|
169
|
+
} else {
|
170
|
+
typeerror(ZQFXBD);
|
171
|
+
}
|
172
|
+
|
173
|
+
return res;
|
174
|
+
}
|
175
|
+
|
176
|
+
static VALUE r_gmpf_div(VALUE self, VALUE arg)
|
177
|
+
{
|
178
|
+
MP_FLOAT *self_val, *res_val, *arg_val_f;
|
179
|
+
MP_RAT *arg_val_q;
|
180
|
+
MP_INT *arg_val_z;
|
181
|
+
VALUE res;
|
182
|
+
unsigned long prec;
|
183
|
+
|
184
|
+
mpf_get_struct_prec (self, self_val, prec);
|
185
|
+
|
186
|
+
if (GMPF_P(arg)) {
|
187
|
+
mpf_get_struct (arg, arg_val_f);
|
188
|
+
prec_max(prec, arg_val_f);
|
189
|
+
mpf_make_struct_init(res, res_val, prec);
|
190
|
+
mpf_div(res_val, self_val, arg_val_f);
|
191
|
+
} else if (GMPQ_P(arg)) {
|
192
|
+
mpq_get_struct (arg, arg_val_q);
|
193
|
+
mpf_make_struct_init(res, res_val, prec);
|
194
|
+
mpf_set_q (res_val, arg_val_q);
|
195
|
+
mpf_div (res_val, self_val, res_val);
|
196
|
+
} else if (GMPZ_P(arg)) {
|
197
|
+
mpz_get_struct (arg, arg_val_z);
|
198
|
+
mpf_make_struct_init(res, res_val, prec);
|
199
|
+
mpf_set_z (res_val, arg_val_z);
|
200
|
+
mpf_div (res_val, self_val, res_val);
|
201
|
+
} else if (FLOAT_P(arg)) {
|
202
|
+
mpf_make_struct_init(res, res_val, prec);
|
203
|
+
mpf_set_d (res_val, FLT2DBL(arg));
|
204
|
+
mpf_div (res_val, self_val, res_val);
|
205
|
+
} else if (FIXNUM_P(arg)) { // _ui with sign control instead ?
|
206
|
+
mpf_make_struct_init(res, res_val, prec);
|
207
|
+
mpf_set_si (res_val, FIX2INT(arg));
|
208
|
+
mpf_div (res_val, self_val, res_val);
|
209
|
+
} else if (BIGNUM_P(arg)) {
|
210
|
+
mpz_temp_from_bignum(arg_val_z, arg);
|
211
|
+
mpf_make_struct_init(res, res_val, prec);
|
212
|
+
mpf_set_z (res_val, arg_val_z);
|
213
|
+
mpf_div (res_val, res_val, self_val);
|
214
|
+
mpz_temp_free(arg_val_z);
|
215
|
+
} else {
|
216
|
+
typeerror(ZQFXBD);
|
217
|
+
}
|
218
|
+
|
219
|
+
return res;
|
220
|
+
}
|
221
|
+
|
222
|
+
#define DEFUN_FLOAT2FLOAT(fname,mpf_fname) \
|
223
|
+
static VALUE r_gmpf_##fname(VALUE self) \
|
224
|
+
{\
|
225
|
+
MP_FLOAT *self_val, *res_val; \
|
226
|
+
VALUE res; \
|
227
|
+
mpf_get_struct(self, self_val); \
|
228
|
+
mpf_make_struct_init(res, res_val, mpf_get_prec(self_val)); \
|
229
|
+
mpf_fname(res_val, self_val); \
|
230
|
+
return res; \
|
231
|
+
}\
|
232
|
+
\
|
233
|
+
static VALUE r_gmpf_##fname##_self(VALUE self) \
|
234
|
+
{\
|
235
|
+
MP_FLOAT *self_val; \
|
236
|
+
mpf_get_struct(self, self_val); \
|
237
|
+
mpf_fname(self_val, self_val); \
|
238
|
+
return Qnil; \
|
239
|
+
}
|
240
|
+
|
241
|
+
DEFUN_FLOAT2FLOAT(abs,mpf_abs)
|
242
|
+
DEFUN_FLOAT2FLOAT(neg,mpf_neg)
|
243
|
+
DEFUN_FLOAT2FLOAT(floor,mpf_floor)
|
244
|
+
DEFUN_FLOAT2FLOAT(trunc,mpf_trunc)
|
245
|
+
DEFUN_FLOAT2FLOAT(ceil,mpf_ceil)
|
246
|
+
|
247
|
+
int mpf_cmp_value(MP_FLOAT *self_val, VALUE arg)
|
248
|
+
{
|
249
|
+
MP_FLOAT *arg_val;
|
250
|
+
int result;
|
251
|
+
|
252
|
+
if (GMPF_P(arg)) {
|
253
|
+
mpf_get_struct(arg,arg_val);
|
254
|
+
return mpf_cmp (self_val, arg_val);
|
255
|
+
} else {
|
256
|
+
mpf_temp_init(arg_val, mpf_get_prec (self_val));
|
257
|
+
mpf_set_value (arg_val, arg);
|
258
|
+
result = mpf_cmp (self_val, arg_val);
|
259
|
+
mpf_temp_free(arg_val);
|
260
|
+
return result;
|
261
|
+
}
|
262
|
+
}
|
263
|
+
|
264
|
+
/* what does really "equal" mean ? it's not obvious */
|
265
|
+
VALUE r_gmpf_eq(VALUE self, VALUE arg)
|
266
|
+
{
|
267
|
+
MP_FLOAT *self_val;
|
268
|
+
mpf_get_struct (self,self_val);
|
269
|
+
return (mpf_cmp_value(self_val, arg) == 0) ? Qtrue : Qfalse;
|
270
|
+
}
|
271
|
+
|
272
|
+
VALUE r_gmpf_cmp (VALUE self, VALUE arg)
|
273
|
+
{
|
274
|
+
MP_FLOAT *self_val;
|
275
|
+
int res;
|
276
|
+
mpf_get_struct (self,self_val);
|
277
|
+
res = mpf_cmp_value(self_val, arg);
|
278
|
+
if (res > 0)
|
279
|
+
return INT2FIX(1);
|
280
|
+
else if (res == 0)
|
281
|
+
return INT2FIX(0);
|
282
|
+
else
|
283
|
+
return INT2FIX(-1);
|
284
|
+
}
|
285
|
+
|
286
|
+
#define DEFUN_FLOAT_CMP(name,CMP_OP) \
|
287
|
+
static VALUE r_gmpf_cmp_##name(VALUE self, VALUE arg) \
|
288
|
+
{ \
|
289
|
+
MP_FLOAT *self_val; \
|
290
|
+
mpf_get_struct (self,self_val); \
|
291
|
+
return (mpf_cmp_value(self_val, arg) CMP_OP 0)?Qtrue:Qfalse; \
|
292
|
+
}
|
293
|
+
|
294
|
+
DEFUN_FLOAT_CMP(lt,<)
|
295
|
+
DEFUN_FLOAT_CMP(le,<=)
|
296
|
+
DEFUN_FLOAT_CMP(gt,>)
|
297
|
+
DEFUN_FLOAT_CMP(ge,>=)
|
298
|
+
|
299
|
+
static VALUE r_gmpf_sgn(VALUE self)
|
300
|
+
{
|
301
|
+
MP_FLOAT *self_val;
|
302
|
+
mpf_get_struct(self, self_val);
|
303
|
+
return INT2FIX(mpf_sgn(self_val));
|
304
|
+
}
|
305
|
+
|
306
|
+
static VALUE r_gmpf_get_prec(VALUE self)
|
307
|
+
{
|
308
|
+
MP_FLOAT *self_val;
|
309
|
+
mpf_get_struct(self, self_val);
|
310
|
+
return INT2NUM(mpf_get_prec(self_val));
|
311
|
+
}
|
312
|
+
|
313
|
+
#ifdef MPFR
|
314
|
+
#define MPFR_SINGLE_FUNCTION(name) \
|
315
|
+
static VALUE r_gmpfr_##name(VALUE self) \
|
316
|
+
{ \
|
317
|
+
MP_FLOAT *self_val, *res_val; \
|
318
|
+
unsigned long prec; \
|
319
|
+
VALUE res; \
|
320
|
+
\
|
321
|
+
mpf_get_struct_prec(self, self_val, prec); \
|
322
|
+
mpf_make_struct_init(res, res_val, prec); \
|
323
|
+
mpfr_##name(res_val, self_val, __gmp_default_rounding_mode); \
|
324
|
+
\
|
325
|
+
return res; \
|
326
|
+
}
|
327
|
+
|
328
|
+
MPFR_SINGLE_FUNCTION(log)
|
329
|
+
MPFR_SINGLE_FUNCTION(exp)
|
330
|
+
MPFR_SINGLE_FUNCTION(sqrt)
|
331
|
+
MPFR_SINGLE_FUNCTION(cos)
|
332
|
+
MPFR_SINGLE_FUNCTION(sin)
|
333
|
+
MPFR_SINGLE_FUNCTION(tan)
|
334
|
+
MPFR_SINGLE_FUNCTION(acos)
|
335
|
+
MPFR_SINGLE_FUNCTION(asin)
|
336
|
+
MPFR_SINGLE_FUNCTION(atan)
|
337
|
+
MPFR_SINGLE_FUNCTION(cosh)
|
338
|
+
MPFR_SINGLE_FUNCTION(sinh)
|
339
|
+
MPFR_SINGLE_FUNCTION(tanh)
|
340
|
+
MPFR_SINGLE_FUNCTION(acosh)
|
341
|
+
MPFR_SINGLE_FUNCTION(asinh)
|
342
|
+
MPFR_SINGLE_FUNCTION(atanh)
|
343
|
+
MPFR_SINGLE_FUNCTION(log1p)
|
344
|
+
MPFR_SINGLE_FUNCTION(expm1)
|
345
|
+
MPFR_SINGLE_FUNCTION(log2)
|
346
|
+
MPFR_SINGLE_FUNCTION(log10)
|
347
|
+
|
348
|
+
static VALUE r_gmpfr_nan_p(VALUE self)
|
349
|
+
{
|
350
|
+
MP_FLOAT *self_val;
|
351
|
+
|
352
|
+
mpf_get_struct(self, self_val);
|
353
|
+
if (mpfr_nan_p(self_val)) {
|
354
|
+
return Qtrue;
|
355
|
+
}
|
356
|
+
else {
|
357
|
+
return Qfalse;
|
358
|
+
}
|
359
|
+
}
|
360
|
+
|
361
|
+
static VALUE r_gmpfr_inf_p(VALUE self)
|
362
|
+
{
|
363
|
+
MP_FLOAT *self_val;
|
364
|
+
|
365
|
+
mpf_get_struct(self, self_val);
|
366
|
+
if (mpfr_inf_p(self_val)) {
|
367
|
+
return Qtrue;
|
368
|
+
}
|
369
|
+
else {
|
370
|
+
return Qfalse;
|
371
|
+
}
|
372
|
+
}
|
373
|
+
|
374
|
+
static VALUE r_gmpfr_fin_p(VALUE self)
|
375
|
+
{
|
376
|
+
if (r_gmpfr_inf_p(self)) {
|
377
|
+
return Qfalse;
|
378
|
+
}
|
379
|
+
else {
|
380
|
+
return Qtrue;
|
381
|
+
}
|
382
|
+
}
|
383
|
+
|
384
|
+
static VALUE r_gmpfr_number_p(VALUE self)
|
385
|
+
{
|
386
|
+
MP_FLOAT *self_val;
|
387
|
+
|
388
|
+
mpf_get_struct(self, self_val);
|
389
|
+
if (mpfr_number_p(self_val)) {
|
390
|
+
return Qtrue;
|
391
|
+
}
|
392
|
+
else {
|
393
|
+
return Qfalse;
|
394
|
+
}
|
395
|
+
}
|
396
|
+
|
397
|
+
static VALUE r_gmpfr_pow(VALUE self, VALUE arg)
|
398
|
+
{
|
399
|
+
MP_FLOAT *self_val, *res_val, *arg_val_f;
|
400
|
+
MP_RAT *arg_val_q;
|
401
|
+
MP_INT *arg_val_z;
|
402
|
+
unsigned long prec;
|
403
|
+
VALUE res;
|
404
|
+
|
405
|
+
mpf_get_struct_prec(self, self_val, prec);
|
406
|
+
|
407
|
+
if (GMPF_P(arg)) {
|
408
|
+
mpf_get_struct(arg, arg_val_f);
|
409
|
+
prec_max(prec, arg_val_f);
|
410
|
+
mpf_make_struct_init(res, res_val, prec);
|
411
|
+
mpfr_pow(res_val, self_val, arg_val_f, __gmp_default_rounding_mode);
|
412
|
+
} else {
|
413
|
+
mpf_make_struct_init(res, res_val, prec);
|
414
|
+
|
415
|
+
if (GMPZ_P(arg)) {
|
416
|
+
mpz_get_struct(arg, arg_val_z);
|
417
|
+
mpf_set_z(res_val, arg_val_z);
|
418
|
+
mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
|
419
|
+
} else if (GMPQ_P(arg)) {
|
420
|
+
mpq_get_struct(arg, arg_val_q);
|
421
|
+
mpf_set_q(res_val, arg_val_q);
|
422
|
+
mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
|
423
|
+
} else if (FLOAT_P(arg)) {
|
424
|
+
mpf_set_d(res_val, FLT2DBL(arg));
|
425
|
+
mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
|
426
|
+
} else if (FIXNUM_P(arg)) {
|
427
|
+
mpfr_pow_si(res_val, self_val, FIX2INT(arg), __gmp_default_rounding_mode);
|
428
|
+
} else if (BIGNUM_P(arg)) {
|
429
|
+
mpz_temp_from_bignum(arg_val_z, arg);
|
430
|
+
mpf_set_z(res_val, arg_val_z);
|
431
|
+
mpz_temp_free(arg_val_z);
|
432
|
+
mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
|
433
|
+
} else {
|
434
|
+
typeerror(ZQFXBD);
|
435
|
+
}
|
436
|
+
|
437
|
+
}
|
438
|
+
|
439
|
+
return res;
|
440
|
+
}
|
441
|
+
|
442
|
+
#endif
|
data/ext/gmpq.h
ADDED
@@ -0,0 +1,486 @@
|
|
1
|
+
static VALUE r_gmpq_add(VALUE self, VALUE arg)
|
2
|
+
{
|
3
|
+
MP_RAT *self_val, *arg_val_q, *res_val;
|
4
|
+
MP_INT *arg_val_z, *res_val_num;
|
5
|
+
VALUE res;
|
6
|
+
|
7
|
+
mpq_get_struct(self, self_val);
|
8
|
+
mpq_make_struct_init(res, res_val);
|
9
|
+
|
10
|
+
if (GMPQ_P(arg)) {
|
11
|
+
mpq_get_struct(arg,arg_val_q);
|
12
|
+
mpq_add (res_val, self_val, arg_val_q);
|
13
|
+
} else if (GMPZ_P(arg)) {
|
14
|
+
res_val_num = mpq_numref(res_val);
|
15
|
+
mpz_set (mpq_denref(res_val), mpq_denref(self_val));
|
16
|
+
mpz_get_struct(arg, arg_val_z);
|
17
|
+
mpz_mul (res_val_num, mpq_denref(self_val), arg_val_z);
|
18
|
+
mpz_add (res_val_num, res_val_num, mpq_numref(self_val));
|
19
|
+
} else if (FIXNUM_P(arg)) {
|
20
|
+
res_val_num = mpq_numref(res_val);
|
21
|
+
mpz_set (mpq_denref(res_val), mpq_denref(self_val));
|
22
|
+
mpz_mul_si (res_val_num, mpq_denref(self_val), FIX2INT(arg));
|
23
|
+
mpz_add (res_val_num, res_val_num, mpq_numref(self_val));
|
24
|
+
} else if (GMPF_P(arg)) {
|
25
|
+
return r_gmpf_add(arg,self);
|
26
|
+
} else if (BIGNUM_P(arg)) {
|
27
|
+
res_val_num = mpq_numref(res_val);
|
28
|
+
mpz_set (mpq_denref(res_val), mpq_denref(self_val));
|
29
|
+
mpz_set_bignum (res_val_num, arg);
|
30
|
+
mpz_mul (res_val_num, res_val_num, mpq_denref(self_val));
|
31
|
+
mpz_add (res_val_num, res_val_num, mpq_numref(self_val));
|
32
|
+
} else {
|
33
|
+
typeerror (ZQFXB);
|
34
|
+
}
|
35
|
+
return res;
|
36
|
+
}
|
37
|
+
|
38
|
+
static VALUE r_gmpq_sub(VALUE self, VALUE arg)
|
39
|
+
{
|
40
|
+
MP_RAT *self_val, *arg_val_q, *res_val;
|
41
|
+
MP_INT *arg_val_z, *res_val_num;
|
42
|
+
MP_FLOAT *arg_val_f, *res_val_f;
|
43
|
+
VALUE res;
|
44
|
+
unsigned int prec;
|
45
|
+
|
46
|
+
mpq_get_struct(self, self_val);
|
47
|
+
mpq_make_struct_init(res, res_val);
|
48
|
+
|
49
|
+
if (GMPQ_P(arg)) {
|
50
|
+
mpq_get_struct(arg,arg_val_q);
|
51
|
+
mpq_sub (res_val, self_val, arg_val_q);
|
52
|
+
} else if (GMPZ_P(arg)) {
|
53
|
+
res_val_num = mpq_numref(res_val);
|
54
|
+
mpz_set (mpq_denref(res_val), mpq_denref(self_val));
|
55
|
+
mpz_get_struct(arg, arg_val_z);
|
56
|
+
mpz_mul (res_val_num, mpq_denref(self_val), arg_val_z);
|
57
|
+
mpz_neg (res_val_num, res_val_num);
|
58
|
+
mpz_add (res_val_num, res_val_num, mpq_numref(self_val));
|
59
|
+
} else if (FIXNUM_P(arg)) {
|
60
|
+
res_val_num = mpq_numref(res_val);
|
61
|
+
mpz_set (mpq_denref(res_val), mpq_denref(self_val));
|
62
|
+
mpz_mul_si (res_val_num, mpq_denref(self_val), -FIX2INT(arg));
|
63
|
+
mpz_add (res_val_num, res_val_num, mpq_numref(self_val));
|
64
|
+
} else if (GMPF_P(arg)) {
|
65
|
+
mpf_get_struct_prec (arg, arg_val_f, prec);
|
66
|
+
mpf_make_struct_init(res, res_val_f, prec);
|
67
|
+
mpf_set_q (res_val_f, self_val);
|
68
|
+
mpf_sub (res_val_f, res_val_f, arg_val_f);
|
69
|
+
} else if (BIGNUM_P(arg)) {
|
70
|
+
res_val_num = mpq_numref(res_val);
|
71
|
+
mpz_set (mpq_denref(res_val), mpq_denref(self_val));
|
72
|
+
mpz_set_bignum (res_val_num, arg);
|
73
|
+
mpz_mul (res_val_num, res_val_num, mpq_denref(self_val));
|
74
|
+
mpz_neg (res_val_num, res_val_num);
|
75
|
+
mpz_add (res_val_num, res_val_num, mpq_numref(self_val));
|
76
|
+
} else {
|
77
|
+
typeerror (ZQFXB);
|
78
|
+
}
|
79
|
+
return res;
|
80
|
+
}
|
81
|
+
|
82
|
+
static VALUE r_gmpq_mul(VALUE self, VALUE arg)
|
83
|
+
{
|
84
|
+
MP_RAT *self_val, *arg_val_q, *res_val;
|
85
|
+
MP_INT *arg_val_z, *tmp_z;
|
86
|
+
VALUE res;
|
87
|
+
#if GMP >= 4
|
88
|
+
unsigned long tmp_ui;
|
89
|
+
#endif
|
90
|
+
|
91
|
+
mpq_get_struct(self, self_val);
|
92
|
+
mpq_make_struct_init(res, res_val);
|
93
|
+
|
94
|
+
if (GMPQ_P(arg)) {
|
95
|
+
mpq_get_struct(arg,arg_val_q);
|
96
|
+
mpq_mul (res_val, self_val, arg_val_q);
|
97
|
+
} else if (GMPZ_P(arg)) {
|
98
|
+
mpz_get_struct(arg,arg_val_z);
|
99
|
+
mpz_temp_init(tmp_z);
|
100
|
+
mpz_gcd (tmp_z, mpq_denref(self_val), arg_val_z);
|
101
|
+
mpz_divexact (mpq_denref(res_val), mpq_denref(self_val), tmp_z);
|
102
|
+
mpz_divexact (mpq_numref(res_val), arg_val_z, tmp_z);
|
103
|
+
mpz_mul (mpq_numref(res_val), mpq_numref(res_val), mpq_numref(self_val));
|
104
|
+
mpz_temp_free(tmp_z);
|
105
|
+
} else if (FIXNUM_P(arg)) {
|
106
|
+
#if GMP >= 4
|
107
|
+
if (FIX2INT(arg) > 0) {
|
108
|
+
tmp_ui = mpz_gcd_ui (0, mpq_denref(self_val), FIX2INT(arg));
|
109
|
+
} else if (FIX2INT(arg) < 0) {
|
110
|
+
tmp_ui = mpz_gcd_ui (0, mpq_denref(self_val), -FIX2INT(arg));
|
111
|
+
} else {
|
112
|
+
mpz_set_ui(mpq_numref(res_val), 0);
|
113
|
+
mpz_set_ui(mpq_denref(res_val), 1);
|
114
|
+
return res;
|
115
|
+
}
|
116
|
+
mpz_divexact_ui (mpq_denref(res_val), mpq_denref(self_val), tmp_ui);
|
117
|
+
mpz_mul_ui (mpq_numref(res_val), mpq_numref(self_val), FIX2INT(arg)/tmp_ui);
|
118
|
+
#else
|
119
|
+
mpz_set (mpq_denref(res_val), mpq_denref(self_val));
|
120
|
+
mpz_mul_si (mpq_numref(res_val), mpq_numref(self_val), FIX2INT(arg));
|
121
|
+
mpq_canonicalize (res_val);
|
122
|
+
#endif
|
123
|
+
} else if (GMPF_P(arg)) {
|
124
|
+
return r_gmpf_mul (arg, self);
|
125
|
+
} else if (BIGNUM_P(arg)) {
|
126
|
+
mpz_temp_alloc(tmp_z);
|
127
|
+
mpz_set_bignum(tmp_z, arg);
|
128
|
+
mpz_gcd(mpq_denref(res_val), mpq_denref(self_val), tmp_z);
|
129
|
+
mpz_divexact(mpq_numref(res_val), tmp_z, mpq_denref(res_val));
|
130
|
+
mpz_divexact(mpq_denref(res_val), mpq_denref(self_val), mpq_denref(res_val));
|
131
|
+
mpz_mul(mpq_numref(res_val), mpq_numref(res_val), mpq_numref(self_val));
|
132
|
+
mpz_temp_free(tmp_z);
|
133
|
+
} else {
|
134
|
+
typeerror (ZQFXB);
|
135
|
+
}
|
136
|
+
return res;
|
137
|
+
}
|
138
|
+
|
139
|
+
static VALUE r_gmpq_div(VALUE self, VALUE arg)
|
140
|
+
{
|
141
|
+
MP_RAT *self_val, *arg_val_q, *res_val;
|
142
|
+
MP_INT *arg_val_z, *tmp_z;
|
143
|
+
MP_FLOAT *arg_val_f, *res_val_f;
|
144
|
+
VALUE res;
|
145
|
+
unsigned long tmp_ui, prec;
|
146
|
+
|
147
|
+
mpq_get_struct(self, self_val);
|
148
|
+
mpq_make_struct_init(res, res_val);
|
149
|
+
|
150
|
+
if (GMPQ_P(arg)) {
|
151
|
+
mpq_get_struct(arg,arg_val_q);
|
152
|
+
if (mpz_sgn(mpq_numref(arg_val_q)) == 0)
|
153
|
+
rb_raise (rb_eZeroDivError, "divided by 0");
|
154
|
+
mpq_div (res_val, self_val, arg_val_q);
|
155
|
+
} else if (GMPZ_P(arg)) {
|
156
|
+
mpz_get_struct(arg,arg_val_z);
|
157
|
+
mpz_temp_init(tmp_z);
|
158
|
+
mpz_gcd (tmp_z, mpq_numref(self_val), arg_val_z);
|
159
|
+
mpz_divexact (mpq_numref(res_val), mpq_numref(self_val), tmp_z);
|
160
|
+
mpz_divexact (mpq_denref(res_val), arg_val_z, tmp_z);
|
161
|
+
mpz_mul (mpq_denref(res_val), mpq_denref(res_val), mpq_denref(self_val));
|
162
|
+
mpz_temp_free(tmp_z);
|
163
|
+
} else if (FIXNUM_P(arg)) {
|
164
|
+
if (FIX2INT(arg) == 0)
|
165
|
+
rb_raise (rb_eZeroDivError, "divided by 0");
|
166
|
+
if (FIX2INT(arg) > 0) {
|
167
|
+
tmp_ui = mpz_gcd_ui (0, mpq_numref(self_val), FIX2INT(arg));
|
168
|
+
} else {
|
169
|
+
tmp_ui = mpz_gcd_ui (0, mpq_numref(self_val), -FIX2INT(arg));
|
170
|
+
}
|
171
|
+
mpz_divexact_ui (mpq_numref(res_val), mpq_numref(self_val), tmp_ui);
|
172
|
+
mpz_mul_ui (mpq_denref(res_val), mpq_denref(self_val), FIX2INT(arg)/tmp_ui);
|
173
|
+
} else if (GMPF_P(arg)) {
|
174
|
+
mpf_get_struct_prec (arg, arg_val_f, prec);
|
175
|
+
mpf_make_struct_init(res, res_val_f, prec);
|
176
|
+
mpf_set_q (res_val_f, self_val);
|
177
|
+
mpf_div (res_val_f, res_val_f, arg_val_f);
|
178
|
+
} else if (BIGNUM_P(arg)) {
|
179
|
+
mpz_temp_alloc(tmp_z);
|
180
|
+
mpz_set_bignum(tmp_z, arg);
|
181
|
+
mpz_gcd(mpq_numref(res_val), mpq_numref(self_val), tmp_z);
|
182
|
+
mpz_divexact(mpq_denref(res_val), tmp_z, mpq_numref(res_val));
|
183
|
+
mpz_divexact(mpq_numref(res_val), mpq_numref(self_val), mpq_numref(res_val));
|
184
|
+
mpz_mul(mpq_denref(res_val), mpq_denref(res_val), mpq_denref(self_val));
|
185
|
+
mpz_temp_free(tmp_z);
|
186
|
+
} else {
|
187
|
+
typeerror (ZQFXB);
|
188
|
+
}
|
189
|
+
return res;
|
190
|
+
}
|
191
|
+
|
192
|
+
static VALUE r_gmpq_neg(VALUE self)
|
193
|
+
{
|
194
|
+
MP_RAT *self_val, *res_val;
|
195
|
+
VALUE res;
|
196
|
+
mpq_get_struct(self, self_val);
|
197
|
+
mpq_make_struct_init(res, res_val);
|
198
|
+
mpq_neg (res_val, self_val);
|
199
|
+
return res;
|
200
|
+
}
|
201
|
+
|
202
|
+
static VALUE r_gmpq_neg_self(VALUE self)
|
203
|
+
{
|
204
|
+
MP_RAT *self_val;
|
205
|
+
mpq_get_struct(self, self_val);
|
206
|
+
mpz_neg (mpq_numref(self_val), mpq_numref(self_val));
|
207
|
+
return Qnil;
|
208
|
+
}
|
209
|
+
|
210
|
+
static VALUE r_gmpq_abs(VALUE self)
|
211
|
+
{
|
212
|
+
MP_RAT *self_val, *res_val;
|
213
|
+
VALUE res;
|
214
|
+
mpq_get_struct(self, self_val);
|
215
|
+
mpq_make_struct_init(res, res_val);
|
216
|
+
mpz_abs (mpq_numref(res_val), mpq_numref(self_val));
|
217
|
+
mpz_set (mpq_denref(res_val), mpq_denref(self_val));
|
218
|
+
|
219
|
+
return res;
|
220
|
+
}
|
221
|
+
|
222
|
+
static VALUE r_gmpq_abs_self(VALUE self)
|
223
|
+
{
|
224
|
+
MP_RAT *self_val;
|
225
|
+
mpq_get_struct(self, self_val);
|
226
|
+
mpz_abs (mpq_numref(self_val), mpq_numref(self_val));
|
227
|
+
return Qnil;
|
228
|
+
}
|
229
|
+
|
230
|
+
static VALUE r_gmpq_inv(VALUE self)
|
231
|
+
{
|
232
|
+
MP_RAT *self_val, *res_val;
|
233
|
+
VALUE res;
|
234
|
+
|
235
|
+
mpq_get_struct(self, self_val);
|
236
|
+
if (mpq_sgn(self_val) == 0)
|
237
|
+
rb_raise (rb_eZeroDivError, "divided by 0");
|
238
|
+
mpq_make_struct_init(res, res_val);
|
239
|
+
mpq_inv (res_val, self_val);
|
240
|
+
|
241
|
+
return res;
|
242
|
+
}
|
243
|
+
|
244
|
+
static VALUE r_gmpq_inv_self(VALUE self)
|
245
|
+
{
|
246
|
+
MP_RAT *self_val;
|
247
|
+
mpq_get_struct(self, self_val);
|
248
|
+
if (mpq_sgn(self_val) == 0)
|
249
|
+
rb_raise (rb_eZeroDivError, "divided by 0");
|
250
|
+
mpq_inv (self_val, self_val);
|
251
|
+
return Qnil;
|
252
|
+
}
|
253
|
+
|
254
|
+
static VALUE r_gmpq_sgn(VALUE self)
|
255
|
+
{
|
256
|
+
MP_RAT *self_val;
|
257
|
+
mpq_get_struct(self, self_val);
|
258
|
+
return INT2FIX(mpq_sgn(self_val));
|
259
|
+
}
|
260
|
+
|
261
|
+
static int mpq_cmp_value (MP_RAT *OP, VALUE arg)
|
262
|
+
{
|
263
|
+
MP_INT *arg_val_z, *tmp_z;
|
264
|
+
MP_RAT *arg_val_q;
|
265
|
+
int res;
|
266
|
+
|
267
|
+
if (GMPQ_P(arg)) {
|
268
|
+
mpq_get_struct(arg,arg_val_q);
|
269
|
+
return mpq_cmp (OP,arg_val_q);
|
270
|
+
} else if (GMPZ_P(arg)) {
|
271
|
+
mpz_get_struct(arg, arg_val_z);
|
272
|
+
mpz_temp_alloc (tmp_z);
|
273
|
+
mpz_init (tmp_z);
|
274
|
+
mpz_mul (tmp_z, mpq_denref(OP), arg_val_z);
|
275
|
+
res = mpz_cmp (mpq_numref(OP),tmp_z);
|
276
|
+
mpz_temp_free (tmp_z);
|
277
|
+
return res;
|
278
|
+
} else if (FIXNUM_P(arg)) {
|
279
|
+
mpz_temp_alloc (tmp_z);
|
280
|
+
mpz_init (tmp_z);
|
281
|
+
mpz_mul_si (tmp_z, mpq_denref(OP), FIX2INT(arg));
|
282
|
+
res = mpz_cmp (mpq_numref(OP), tmp_z);
|
283
|
+
mpz_temp_free (tmp_z);
|
284
|
+
return res;
|
285
|
+
} else if (GMPF_P(arg)) {
|
286
|
+
not_yet;
|
287
|
+
} else if (BIGNUM_P(arg)) {
|
288
|
+
mpz_temp_from_bignum (tmp_z, arg);
|
289
|
+
mpz_mul (tmp_z, tmp_z, mpq_denref(OP));
|
290
|
+
res = mpz_cmp (mpq_numref(OP), tmp_z);
|
291
|
+
mpz_temp_free (tmp_z);
|
292
|
+
return res;
|
293
|
+
} else {
|
294
|
+
typeerror (ZQFXB);
|
295
|
+
}
|
296
|
+
}
|
297
|
+
|
298
|
+
static VALUE r_gmpq_eq(VALUE self, VALUE arg)
|
299
|
+
{
|
300
|
+
MP_RAT *self_val, *arg_val_q;
|
301
|
+
MP_INT *arg_val_z;
|
302
|
+
|
303
|
+
mpq_get_struct(self,self_val);
|
304
|
+
if (GMPQ_P(arg)) {
|
305
|
+
mpq_get_struct(arg,arg_val_q);
|
306
|
+
return mpq_equal(self_val,arg_val_q)?Qtrue:Qfalse;
|
307
|
+
} else if (GMPZ_P(arg)) {
|
308
|
+
if (mpz_cmp_ui(mpq_denref(self_val), 1) != 0)
|
309
|
+
return Qfalse;
|
310
|
+
mpz_get_struct (arg, arg_val_z);
|
311
|
+
return (mpz_cmp(mpq_numref(self_val),arg_val_z)==0)?Qtrue:Qfalse;
|
312
|
+
} else if (FIXNUM_P(arg)) {
|
313
|
+
if (mpz_cmp_ui(mpq_denref(self_val), 1) != 0)
|
314
|
+
return Qfalse;
|
315
|
+
return (mpz_cmp_ui(mpq_numref(self_val),FIX2INT(arg))==0)?Qtrue:Qfalse;
|
316
|
+
} else if (BIGNUM_P(arg)) {
|
317
|
+
if (mpz_cmp_ui(mpq_denref(self_val), 1) != 0)
|
318
|
+
return Qfalse;
|
319
|
+
mpz_temp_from_bignum(arg_val_z, arg);
|
320
|
+
if (mpz_cmp (mpq_numref(self_val),arg_val_z) == 0) {
|
321
|
+
mpz_temp_free (arg_val_z);
|
322
|
+
return Qtrue;
|
323
|
+
} else {
|
324
|
+
mpz_temp_free (arg_val_z);
|
325
|
+
return Qfalse;
|
326
|
+
}
|
327
|
+
} else {
|
328
|
+
return Qfalse;
|
329
|
+
}
|
330
|
+
}
|
331
|
+
|
332
|
+
static VALUE r_gmpq_cmp(VALUE self, VALUE arg)
|
333
|
+
{
|
334
|
+
MP_RAT *self_val;
|
335
|
+
int res;
|
336
|
+
mpq_get_struct (self,self_val);
|
337
|
+
res = mpq_cmp_value(self_val, arg);
|
338
|
+
if (res > 0)
|
339
|
+
return INT2FIX(1);
|
340
|
+
else if (res == 0)
|
341
|
+
return INT2FIX(0);
|
342
|
+
else
|
343
|
+
return INT2FIX(-1);
|
344
|
+
}
|
345
|
+
|
346
|
+
#define DEFUN_RAT_CMP(name,CMP_OP) \
|
347
|
+
static VALUE r_gmpq_cmp_##name(VALUE self, VALUE arg) \
|
348
|
+
{ \
|
349
|
+
MP_RAT *self_val; \
|
350
|
+
mpq_get_struct (self,self_val); \
|
351
|
+
return (mpq_cmp_value(self_val, arg) CMP_OP 0)?Qtrue:Qfalse; \
|
352
|
+
}
|
353
|
+
|
354
|
+
DEFUN_RAT_CMP(lt,<)
|
355
|
+
DEFUN_RAT_CMP(le,<=)
|
356
|
+
DEFUN_RAT_CMP(gt,>)
|
357
|
+
DEFUN_RAT_CMP(ge,>=)
|
358
|
+
|
359
|
+
static VALUE r_gmpq_swap(VALUE self, VALUE arg)
|
360
|
+
{
|
361
|
+
MP_RAT *self_val, *arg_val;
|
362
|
+
|
363
|
+
if (!GMPQ_P(arg)) {
|
364
|
+
rb_raise(rb_eTypeError, "Can't swap GMP::Q with object of other class");
|
365
|
+
}
|
366
|
+
|
367
|
+
mpq_get_struct(self, self_val);
|
368
|
+
mpq_get_struct(arg, arg_val);
|
369
|
+
mpq_swap(self_val,arg_val);
|
370
|
+
|
371
|
+
return Qnil;
|
372
|
+
}
|
373
|
+
|
374
|
+
#define DEFUN_RAT2INT(fname,mpz_fname) \
|
375
|
+
static VALUE r_gmpq_##fname(VALUE self) \
|
376
|
+
{ \
|
377
|
+
MP_RAT *self_val; \
|
378
|
+
MP_INT *res_val; \
|
379
|
+
VALUE res; \
|
380
|
+
\
|
381
|
+
mpq_get_struct(self, self_val); \
|
382
|
+
mpz_make_struct_init (res, res_val) \
|
383
|
+
mpz_fname (res_val, mpq_numref(self_val), mpq_denref(self_val)); \
|
384
|
+
return res; \
|
385
|
+
}
|
386
|
+
|
387
|
+
DEFUN_RAT2INT(floor,mpz_fdiv_q)
|
388
|
+
DEFUN_RAT2INT(trunc,mpz_tdiv_q)
|
389
|
+
DEFUN_RAT2INT(ceil,mpz_cdiv_q)
|
390
|
+
|
391
|
+
static VALUE r_gmpq_to_d(VALUE self)
|
392
|
+
{
|
393
|
+
MP_RAT *self_val;
|
394
|
+
mpq_get_struct (self, self_val);
|
395
|
+
|
396
|
+
return rb_float_new(mpq_get_d(self_val));
|
397
|
+
}
|
398
|
+
|
399
|
+
static VALUE r_gmpq_cmpabs (VALUE self, VALUE arg)
|
400
|
+
{
|
401
|
+
MP_RAT *arg_val_q, *self_val;
|
402
|
+
MP_INT *arg_val_z, *tmp_z;
|
403
|
+
int res;
|
404
|
+
int sgnt;
|
405
|
+
|
406
|
+
mpq_get_struct(self, self_val);
|
407
|
+
|
408
|
+
if (GMPQ_P(arg)) {
|
409
|
+
mpq_get_struct(arg,arg_val_q);
|
410
|
+
sgnt = 3*mpz_sgn(mpq_numref(self_val)) + mpz_sgn(mpq_numref(arg_val_q));
|
411
|
+
switch (sgnt)
|
412
|
+
{
|
413
|
+
default:
|
414
|
+
case 0:
|
415
|
+
return INT2FIX(0);
|
416
|
+
case 1:
|
417
|
+
case -1:
|
418
|
+
return INT2FIX(-1);
|
419
|
+
case 2:
|
420
|
+
tmp_z = mpq_numref(arg_val_q);
|
421
|
+
mpz_neg (tmp_z, tmp_z);
|
422
|
+
res = mpq_cmp (self_val, arg_val_q);
|
423
|
+
mpz_neg (tmp_z, tmp_z);
|
424
|
+
return res;
|
425
|
+
case -2:
|
426
|
+
tmp_z = mpq_numref(arg_val_q);
|
427
|
+
mpz_neg (tmp_z, tmp_z);
|
428
|
+
res = mpq_cmp (self_val, arg_val_q);
|
429
|
+
mpz_neg (tmp_z, tmp_z);
|
430
|
+
return res;
|
431
|
+
case 3:
|
432
|
+
case -3:
|
433
|
+
return INT2FIX(1);
|
434
|
+
case 4:
|
435
|
+
case -4:
|
436
|
+
return INT2FIX(mpq_cmp (self_val,arg_val_q));
|
437
|
+
}
|
438
|
+
} else if (GMPZ_P(arg)) {
|
439
|
+
mpz_get_struct(arg, arg_val_z);
|
440
|
+
mpz_temp_alloc (tmp_z);
|
441
|
+
mpz_init (tmp_z);
|
442
|
+
mpz_mul (tmp_z, mpq_denref(self_val), arg_val_z);
|
443
|
+
res = mpz_cmpabs (mpq_numref(self_val),tmp_z);
|
444
|
+
mpz_temp_free (tmp_z);
|
445
|
+
return res;
|
446
|
+
} else if (FIXNUM_P(arg)) {
|
447
|
+
mpz_temp_alloc (tmp_z);
|
448
|
+
mpz_init (tmp_z);
|
449
|
+
mpz_mul_si (tmp_z, mpq_denref(self_val), FIX2INT(arg));
|
450
|
+
res = mpz_cmpabs (mpq_numref(self_val), tmp_z);
|
451
|
+
mpz_temp_free (tmp_z);
|
452
|
+
return res;
|
453
|
+
} else if (GMPF_P(arg)) {
|
454
|
+
not_yet;
|
455
|
+
} else if (BIGNUM_P(arg)) {
|
456
|
+
mpz_temp_from_bignum (tmp_z, arg);
|
457
|
+
mpz_mul (tmp_z, tmp_z, mpq_denref(self_val));
|
458
|
+
res = mpz_cmpabs (mpq_numref(self_val), tmp_z);
|
459
|
+
mpz_temp_free (tmp_z);
|
460
|
+
return res;
|
461
|
+
} else {
|
462
|
+
typeerror (ZQFXB);
|
463
|
+
}
|
464
|
+
}
|
465
|
+
|
466
|
+
static VALUE r_gmpq_num(VALUE self)
|
467
|
+
{
|
468
|
+
MP_RAT *self_val;
|
469
|
+
MP_INT *res_val;
|
470
|
+
VALUE res;
|
471
|
+
mpq_get_struct(self,self_val);
|
472
|
+
mpz_make_struct(res, res_val);
|
473
|
+
mpz_init_set (res_val, mpq_numref (self_val));
|
474
|
+
return res;
|
475
|
+
}
|
476
|
+
|
477
|
+
static VALUE r_gmpq_den(VALUE self)
|
478
|
+
{
|
479
|
+
MP_RAT *self_val;
|
480
|
+
MP_INT *res_val;
|
481
|
+
VALUE res;
|
482
|
+
mpq_get_struct(self,self_val);
|
483
|
+
mpz_make_struct(res, res_val);
|
484
|
+
mpz_init_set (res_val, mpq_denref (self_val));
|
485
|
+
return res;
|
486
|
+
}
|