srawlins-gmp 0.1.4.2 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (6) hide show
  1. data/README.rdoc +21 -18
  2. data/ext/gmp.c +17 -216
  3. data/ext/gmpf.h +11 -309
  4. data/ext/gmpq.h +8 -482
  5. data/ext/gmpz.h +5 -818
  6. metadata +1 -1
data/ext/gmpq.h CHANGED
@@ -1,486 +1,12 @@
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;
1
+ #ifndef _GMPQ_H_
2
+ #define _GMPQ_H_
6
3
 
7
- mpq_get_struct(self, self_val);
8
- mpq_make_struct_init(res, res_val);
4
+ /*
5
+ * gmpq.h
6
+ *
7
+ * This file contains GMP::Q stuff.
8
+ */
9
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
- }
10
+ #include <ruby_gmp.h>
37
11
 
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
12
  #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
- }