gmp 0.1.7
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 +47 -0
- data/INSTALL +4 -0
- data/README.rdoc +257 -0
- data/ext/extconf.rb +30 -0
- data/ext/gmp.c +195 -0
- data/ext/gmpf.c +584 -0
- data/ext/gmpf.h +144 -0
- data/ext/gmpq.c +774 -0
- data/ext/gmpq.h +12 -0
- data/ext/gmpz.c +1774 -0
- data/ext/gmpz.h +20 -0
- data/ext/ruby_gmp.h +199 -0
- data/ext/takeover.h +36 -0
- data/manual.tex +183 -0
- data/test/README +41 -0
- data/test/tc_cmp.rb +74 -0
- data/test/tc_fib_fac_nextprime.rb +51 -0
- data/test/tc_floor_ceil_truncate.rb +21 -0
- data/test/tc_logical_roots.rb +48 -0
- data/test/tc_q.rb +27 -0
- data/test/tc_q_basic.rb +41 -0
- data/test/tc_sgn_neg_abs.rb +47 -0
- data/test/tc_swap.rb +19 -0
- data/test/tc_z.rb +71 -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/tc_z_shifts_last_bits.rb +22 -0
- data/test/tc_z_to_d_to_i.rb +24 -0
- data/test/tc_zerodivisionexceptions.rb +17 -0
- data/test/test_helper.rb +2 -0
- data/test/unit_tests.rb +135 -0
- metadata +89 -0
data/ext/gmpf.c
ADDED
@@ -0,0 +1,584 @@
|
|
1
|
+
#include <gmpz.h>
|
2
|
+
#include <gmpq.h>
|
3
|
+
#include <gmpf.h>
|
4
|
+
|
5
|
+
/*
|
6
|
+
* Document-class: GMP::F
|
7
|
+
*
|
8
|
+
* GMP Multiple Precision floating point numbers.
|
9
|
+
*
|
10
|
+
* Instances of this class can store variables of the type mpf_t. This class
|
11
|
+
* also contains many methods that act as the functions for mpf_t variables,
|
12
|
+
* as well as a few methods that attempt to make this library more Ruby-ish.
|
13
|
+
*/
|
14
|
+
|
15
|
+
/**********************************************************************
|
16
|
+
* Macros *
|
17
|
+
**********************************************************************/
|
18
|
+
|
19
|
+
#define DEFUN_FLOAT2FLOAT(fname,mpf_fname) \
|
20
|
+
static VALUE r_gmpf_##fname(VALUE self) \
|
21
|
+
{ \
|
22
|
+
MP_FLOAT *self_val, *res_val; \
|
23
|
+
VALUE res; \
|
24
|
+
mpf_get_struct(self, self_val); \
|
25
|
+
mpf_make_struct_init(res, res_val, mpf_get_prec(self_val)); \
|
26
|
+
mpf_fname(res_val, self_val); \
|
27
|
+
return res; \
|
28
|
+
} \
|
29
|
+
\
|
30
|
+
static VALUE r_gmpf_##fname##_self(VALUE self) \
|
31
|
+
{ \
|
32
|
+
MP_FLOAT *self_val; \
|
33
|
+
mpf_get_struct(self, self_val); \
|
34
|
+
mpf_fname(self_val, self_val); \
|
35
|
+
return Qnil; \
|
36
|
+
}
|
37
|
+
|
38
|
+
#define DEFUN_FLOAT_CMP(name,CMP_OP) \
|
39
|
+
static VALUE r_gmpf_cmp_##name(VALUE self, VALUE arg) \
|
40
|
+
{ \
|
41
|
+
MP_FLOAT *self_val; \
|
42
|
+
mpf_get_struct(self,self_val); \
|
43
|
+
return (mpf_cmp_value(self_val, arg) CMP_OP 0)?Qtrue:Qfalse; \
|
44
|
+
}
|
45
|
+
|
46
|
+
|
47
|
+
/**********************************************************************
|
48
|
+
* Initializing, Assigning Floats *
|
49
|
+
**********************************************************************/
|
50
|
+
|
51
|
+
/*
|
52
|
+
* call-seq:
|
53
|
+
* GMP::R.new(arg)
|
54
|
+
*
|
55
|
+
* Creates a new GMP::R float, with arg as its value, converting where
|
56
|
+
* necessary.
|
57
|
+
*/
|
58
|
+
VALUE r_gmpfsg_new(int argc, VALUE *argv, VALUE klass)
|
59
|
+
{
|
60
|
+
MP_FLOAT *res_val;
|
61
|
+
VALUE res;
|
62
|
+
|
63
|
+
(void)klass;
|
64
|
+
|
65
|
+
if (argc > 2)
|
66
|
+
rb_raise(rb_eArgError, "wrong # of arguments(%d for 0, 1 or 2)", argc);
|
67
|
+
|
68
|
+
mpf_make_struct (res, res_val);
|
69
|
+
rb_obj_call_init(res, argc, argv);
|
70
|
+
|
71
|
+
return res;
|
72
|
+
}
|
73
|
+
|
74
|
+
VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
|
75
|
+
{
|
76
|
+
MP_FLOAT *self_val, *arg_val_f;
|
77
|
+
unsigned long prec = 0;
|
78
|
+
VALUE arg;
|
79
|
+
|
80
|
+
mpf_get_struct (self, self_val);
|
81
|
+
|
82
|
+
if (argc==0) {
|
83
|
+
mpf_init(self_val);
|
84
|
+
mpf_set_si(self_val, 0);
|
85
|
+
return Qnil;
|
86
|
+
}
|
87
|
+
|
88
|
+
arg = argv[0];
|
89
|
+
|
90
|
+
if (argc == 2) {
|
91
|
+
if (FIXNUM_P(argv[1])) {
|
92
|
+
if (FIX2INT(argv[1]) >= 0)
|
93
|
+
prec = FIX2INT(argv[1]);
|
94
|
+
else
|
95
|
+
rb_raise(rb_eRangeError, "prec must be non-negative");
|
96
|
+
} else {
|
97
|
+
rb_raise(rb_eTypeError, "prec must be FixNum");
|
98
|
+
}
|
99
|
+
} else if (GMPF_P(arg)) {
|
100
|
+
mpf_get_struct (arg, arg_val_f);
|
101
|
+
prec = mpf_get_prec (arg_val_f);
|
102
|
+
}
|
103
|
+
if (prec == 0)
|
104
|
+
mpf_init (self_val);
|
105
|
+
else
|
106
|
+
mpf_init2 (self_val, prec);
|
107
|
+
|
108
|
+
if (GMPF_P(arg)) {
|
109
|
+
mpf_get_struct (arg, arg_val_f);
|
110
|
+
mpf_set(self_val, arg_val_f);
|
111
|
+
} else {
|
112
|
+
mpf_set_value(self_val, arg);
|
113
|
+
}
|
114
|
+
|
115
|
+
return Qnil;
|
116
|
+
}
|
117
|
+
|
118
|
+
/*
|
119
|
+
* call-seq:
|
120
|
+
* GMP::F(arg)
|
121
|
+
*
|
122
|
+
* A convenience method for +GMP::F.new(arg)+.
|
123
|
+
*/
|
124
|
+
VALUE r_gmpmod_f(int argc, VALUE *argv, VALUE module)
|
125
|
+
{
|
126
|
+
(void)module;
|
127
|
+
return r_gmpfsg_new(argc, argv, cGMP_F);
|
128
|
+
}
|
129
|
+
|
130
|
+
|
131
|
+
/**********************************************************************
|
132
|
+
* Converting Floats *
|
133
|
+
**********************************************************************/
|
134
|
+
|
135
|
+
VALUE r_gmpf_to_d(VALUE self)
|
136
|
+
{
|
137
|
+
MP_FLOAT *self_val;
|
138
|
+
mpf_get_struct(self, self_val);
|
139
|
+
|
140
|
+
return rb_float_new(mpf_get_d(self_val));
|
141
|
+
}
|
142
|
+
|
143
|
+
/*
|
144
|
+
* Document-method: to_s
|
145
|
+
*
|
146
|
+
* call-seq:
|
147
|
+
* float.to_s
|
148
|
+
*
|
149
|
+
* Returns the decimal representation of +float+, as a string.
|
150
|
+
*/
|
151
|
+
VALUE r_gmpf_to_s(VALUE self)
|
152
|
+
{
|
153
|
+
MP_FLOAT *self_val;
|
154
|
+
char *str, *str2;
|
155
|
+
VALUE res;
|
156
|
+
mp_exp_t exponent;
|
157
|
+
|
158
|
+
mpf_get_struct(self, self_val);
|
159
|
+
|
160
|
+
str = mpf_get_str(NULL, &exponent, 10, 0, self_val);
|
161
|
+
if ((strcmp(str, "NaN") == 0) ||
|
162
|
+
(strcmp(str, "Inf") == 0) ||
|
163
|
+
(strcmp(str, "-Inf") == 0))
|
164
|
+
{
|
165
|
+
res = rb_str_new2(str);
|
166
|
+
}
|
167
|
+
else
|
168
|
+
{
|
169
|
+
if (str[0] == '-')
|
170
|
+
__gmp_asprintf(&str2, "-0.%se%+ld", str+1, exponent);
|
171
|
+
else
|
172
|
+
__gmp_asprintf(&str2, "0.%se%+ld", str, exponent);
|
173
|
+
res = rb_str_new2(str2);
|
174
|
+
free(str2);
|
175
|
+
}
|
176
|
+
free(str);
|
177
|
+
return res;
|
178
|
+
}
|
179
|
+
|
180
|
+
|
181
|
+
/**********************************************************************
|
182
|
+
* Float Arithmetic *
|
183
|
+
**********************************************************************/
|
184
|
+
|
185
|
+
/*
|
186
|
+
* call-seq:
|
187
|
+
* float + other
|
188
|
+
*
|
189
|
+
* Returns the sum of +float+ and +other+. +other+ can be
|
190
|
+
* * GMP::Z
|
191
|
+
* * Fixnum
|
192
|
+
* * GMP::Q
|
193
|
+
* * GMP::F
|
194
|
+
* * Bignum
|
195
|
+
* * Float
|
196
|
+
*/
|
197
|
+
VALUE r_gmpf_add(VALUE self, VALUE arg)
|
198
|
+
{
|
199
|
+
MP_FLOAT *self_val, *res_val, *arg_val_f;
|
200
|
+
MP_RAT *arg_val_q;
|
201
|
+
MP_INT *arg_val_z;
|
202
|
+
VALUE res;
|
203
|
+
unsigned long prec;
|
204
|
+
|
205
|
+
mpf_get_struct_prec (self, self_val, prec);
|
206
|
+
|
207
|
+
if (GMPF_P(arg)) {
|
208
|
+
mpf_get_struct (arg, arg_val_f);
|
209
|
+
prec_max(prec, arg_val_f);
|
210
|
+
mpf_make_struct_init(res, res_val, prec);
|
211
|
+
mpf_add(res_val, self_val, arg_val_f);
|
212
|
+
} else if (GMPQ_P(arg)) {
|
213
|
+
mpq_get_struct (arg, arg_val_q);
|
214
|
+
mpf_make_struct_init(res, res_val, prec);
|
215
|
+
mpf_set_q (res_val, arg_val_q);
|
216
|
+
mpf_add (res_val, res_val, self_val);
|
217
|
+
} else if (GMPZ_P(arg)) {
|
218
|
+
mpz_get_struct (arg, arg_val_z);
|
219
|
+
mpf_make_struct_init(res, res_val, prec);
|
220
|
+
mpf_set_z (res_val, arg_val_z);
|
221
|
+
mpf_add (res_val, res_val, self_val);
|
222
|
+
} else if (FLOAT_P(arg)) {
|
223
|
+
mpf_make_struct_init(res, res_val, prec);
|
224
|
+
mpf_set_d (res_val, NUM2DBL(arg));
|
225
|
+
mpf_add (res_val, res_val, self_val);
|
226
|
+
} else if (FIXNUM_P(arg)) { // _ui with sign control instead ?
|
227
|
+
mpf_make_struct_init(res, res_val, prec);
|
228
|
+
mpf_set_si (res_val, FIX2INT(arg));
|
229
|
+
mpf_add (res_val, res_val, self_val);
|
230
|
+
} else if (BIGNUM_P(arg)) {
|
231
|
+
mpz_temp_from_bignum(arg_val_z, arg);
|
232
|
+
mpf_make_struct_init(res, res_val, prec);
|
233
|
+
mpf_set_z (res_val, arg_val_z);
|
234
|
+
mpf_add (res_val, res_val, self_val);
|
235
|
+
mpz_temp_free(arg_val_z);
|
236
|
+
} else {
|
237
|
+
typeerror(ZQFXBD);
|
238
|
+
}
|
239
|
+
|
240
|
+
return res;
|
241
|
+
}
|
242
|
+
|
243
|
+
/*
|
244
|
+
* call-seq:
|
245
|
+
* float1 - float2
|
246
|
+
*
|
247
|
+
* Subtracts +float2+ from +float1+. +float2+ can be
|
248
|
+
* * GMP::Z
|
249
|
+
* * Fixnum
|
250
|
+
* * GMP::Q
|
251
|
+
* * GMP::F
|
252
|
+
* * Bignum
|
253
|
+
* * Float
|
254
|
+
*/
|
255
|
+
VALUE r_gmpf_sub(VALUE self, VALUE arg)
|
256
|
+
{
|
257
|
+
MP_FLOAT *self_val, *res_val, *arg_val_f;
|
258
|
+
MP_RAT *arg_val_q;
|
259
|
+
MP_INT *arg_val_z;
|
260
|
+
VALUE res;
|
261
|
+
unsigned long prec;
|
262
|
+
|
263
|
+
mpf_get_struct_prec (self, self_val, prec);
|
264
|
+
|
265
|
+
if (GMPF_P(arg)) {
|
266
|
+
mpf_get_struct(arg, arg_val_f);
|
267
|
+
prec_max(prec, arg_val_f);
|
268
|
+
mpf_make_struct_init(res, res_val, prec);
|
269
|
+
mpf_sub(res_val, self_val, arg_val_f);
|
270
|
+
} else if (GMPQ_P(arg)) {
|
271
|
+
mpq_get_struct(arg, arg_val_q);
|
272
|
+
mpf_make_struct_init(res, res_val, prec);
|
273
|
+
mpf_set_q(res_val, arg_val_q);
|
274
|
+
mpf_sub(res_val, self_val, res_val);
|
275
|
+
} else if (GMPZ_P(arg)) {
|
276
|
+
mpz_get_struct(arg, arg_val_z);
|
277
|
+
mpf_make_struct_init(res, res_val, prec);
|
278
|
+
mpf_set_z(res_val, arg_val_z);
|
279
|
+
mpf_sub(res_val, self_val, res_val);
|
280
|
+
} else if (FLOAT_P(arg)) {
|
281
|
+
mpf_make_struct_init(res, res_val, prec);
|
282
|
+
mpf_set_d(res_val, NUM2DBL(arg));
|
283
|
+
mpf_sub(res_val, self_val, res_val);
|
284
|
+
} else if (FIXNUM_P(arg)) { // _ui with sign control instead ?
|
285
|
+
mpf_make_struct_init(res, res_val, prec);
|
286
|
+
mpf_set_si(res_val, FIX2INT(arg));
|
287
|
+
mpf_sub(res_val, self_val, res_val);
|
288
|
+
} else if (BIGNUM_P(arg)) {
|
289
|
+
mpz_temp_from_bignum(arg_val_z, arg);
|
290
|
+
mpf_make_struct_init(res, res_val, prec);
|
291
|
+
mpf_set_z(res_val, arg_val_z);
|
292
|
+
mpf_sub(res_val, self_val, res_val);
|
293
|
+
mpz_temp_free(arg_val_z);
|
294
|
+
} else {
|
295
|
+
typeerror(ZQFXBD);
|
296
|
+
}
|
297
|
+
|
298
|
+
return res;
|
299
|
+
}
|
300
|
+
|
301
|
+
/*
|
302
|
+
* call-seq:
|
303
|
+
* float * other
|
304
|
+
*
|
305
|
+
* Returns the product of +float+ and +other+. +other+ can be
|
306
|
+
* * GMP::Z
|
307
|
+
* * Fixnum
|
308
|
+
* * GMP::Q
|
309
|
+
* * GMP::F
|
310
|
+
* * Bignum
|
311
|
+
* * Float
|
312
|
+
*/
|
313
|
+
VALUE r_gmpf_mul(VALUE self, VALUE arg)
|
314
|
+
{
|
315
|
+
MP_FLOAT *self_val, *res_val, *arg_val_f;
|
316
|
+
MP_RAT *arg_val_q;
|
317
|
+
MP_INT *arg_val_z;
|
318
|
+
VALUE res;
|
319
|
+
unsigned long prec;
|
320
|
+
|
321
|
+
mpf_get_struct_prec (self, self_val, prec);
|
322
|
+
|
323
|
+
if (GMPF_P(arg)) {
|
324
|
+
mpf_get_struct(arg, arg_val_f);
|
325
|
+
prec_max(prec, arg_val_f);
|
326
|
+
mpf_make_struct_init(res, res_val, prec);
|
327
|
+
mpf_mul(res_val, self_val, arg_val_f);
|
328
|
+
} else if (GMPQ_P(arg)) {
|
329
|
+
mpq_get_struct(arg, arg_val_q);
|
330
|
+
mpf_make_struct_init(res, res_val, prec);
|
331
|
+
mpf_set_q(res_val, arg_val_q);
|
332
|
+
mpf_mul(res_val, self_val, res_val);
|
333
|
+
} else if (GMPZ_P(arg)) {
|
334
|
+
mpz_get_struct(arg, arg_val_z);
|
335
|
+
mpf_make_struct_init(res, res_val, prec);
|
336
|
+
mpf_set_z(res_val, arg_val_z);
|
337
|
+
mpf_mul(res_val, self_val, res_val);
|
338
|
+
} else if (FLOAT_P(arg)) {
|
339
|
+
mpf_make_struct_init(res, res_val, prec);
|
340
|
+
mpf_set_d(res_val, NUM2DBL(arg));
|
341
|
+
mpf_mul(res_val, self_val, res_val);
|
342
|
+
} else if (FIXNUM_P(arg)) { // _ui with sign control instead ?
|
343
|
+
mpf_make_struct_init(res, res_val, prec);
|
344
|
+
mpf_set_si(res_val, FIX2INT(arg));
|
345
|
+
mpf_mul(res_val, self_val, res_val);
|
346
|
+
} else if (BIGNUM_P(arg)) {
|
347
|
+
mpz_temp_from_bignum(arg_val_z, arg);
|
348
|
+
mpf_make_struct_init(res, res_val, prec);
|
349
|
+
mpf_set_z(res_val, arg_val_z);
|
350
|
+
mpf_mul(res_val, res_val, self_val);
|
351
|
+
mpz_temp_free(arg_val_z);
|
352
|
+
} else {
|
353
|
+
typeerror(ZQFXBD);
|
354
|
+
}
|
355
|
+
|
356
|
+
return res;
|
357
|
+
}
|
358
|
+
|
359
|
+
/*
|
360
|
+
* call-seq:
|
361
|
+
* float1 / float2
|
362
|
+
*
|
363
|
+
* Divides +float1+ by +float2+. +float2+ can be
|
364
|
+
* * GMP::Z
|
365
|
+
* * Fixnum
|
366
|
+
* * GMP::Q
|
367
|
+
* * GMP::F
|
368
|
+
* * Bignum
|
369
|
+
* * Float
|
370
|
+
*/
|
371
|
+
VALUE r_gmpf_div(VALUE self, VALUE arg)
|
372
|
+
{
|
373
|
+
MP_FLOAT *self_val, *res_val, *arg_val_f;
|
374
|
+
MP_RAT *arg_val_q;
|
375
|
+
MP_INT *arg_val_z;
|
376
|
+
VALUE res;
|
377
|
+
unsigned long prec;
|
378
|
+
|
379
|
+
mpf_get_struct_prec (self, self_val, prec);
|
380
|
+
|
381
|
+
if (GMPF_P(arg)) {
|
382
|
+
mpf_get_struct (arg, arg_val_f);
|
383
|
+
prec_max(prec, arg_val_f);
|
384
|
+
mpf_make_struct_init(res, res_val, prec);
|
385
|
+
mpf_div(res_val, self_val, arg_val_f);
|
386
|
+
} else if (GMPQ_P(arg)) {
|
387
|
+
mpq_get_struct (arg, arg_val_q);
|
388
|
+
mpf_make_struct_init(res, res_val, prec);
|
389
|
+
mpf_set_q (res_val, arg_val_q);
|
390
|
+
mpf_div (res_val, self_val, res_val);
|
391
|
+
} else if (GMPZ_P(arg)) {
|
392
|
+
mpz_get_struct (arg, arg_val_z);
|
393
|
+
mpf_make_struct_init(res, res_val, prec);
|
394
|
+
mpf_set_z (res_val, arg_val_z);
|
395
|
+
mpf_div (res_val, self_val, res_val);
|
396
|
+
} else if (FLOAT_P(arg)) {
|
397
|
+
mpf_make_struct_init(res, res_val, prec);
|
398
|
+
mpf_set_d (res_val, NUM2DBL(arg));
|
399
|
+
mpf_div (res_val, self_val, res_val);
|
400
|
+
} else if (FIXNUM_P(arg)) { // _ui with sign control instead ?
|
401
|
+
mpf_make_struct_init(res, res_val, prec);
|
402
|
+
mpf_set_si (res_val, FIX2INT(arg));
|
403
|
+
mpf_div (res_val, self_val, res_val);
|
404
|
+
} else if (BIGNUM_P(arg)) {
|
405
|
+
mpz_temp_from_bignum(arg_val_z, arg);
|
406
|
+
mpf_make_struct_init(res, res_val, prec);
|
407
|
+
mpf_set_z (res_val, arg_val_z);
|
408
|
+
mpf_div (res_val, self_val, res_val);
|
409
|
+
mpz_temp_free(arg_val_z);
|
410
|
+
} else {
|
411
|
+
typeerror(ZQFXBD);
|
412
|
+
}
|
413
|
+
|
414
|
+
return res;
|
415
|
+
}
|
416
|
+
|
417
|
+
/*
|
418
|
+
* Document-method: neg
|
419
|
+
*
|
420
|
+
* call-seq:
|
421
|
+
* float.neg
|
422
|
+
* -float
|
423
|
+
*
|
424
|
+
* From the GMP Manual:
|
425
|
+
*
|
426
|
+
* Returns -+float+.
|
427
|
+
*/
|
428
|
+
/*
|
429
|
+
* Document-method: neg!
|
430
|
+
*
|
431
|
+
* call-seq:
|
432
|
+
* float.neg!
|
433
|
+
*
|
434
|
+
* Sets +float+ to -+float+.
|
435
|
+
*/
|
436
|
+
DEFUN_FLOAT2FLOAT(neg,mpf_neg)
|
437
|
+
/*
|
438
|
+
* Document-method: abs
|
439
|
+
*
|
440
|
+
* call-seq:
|
441
|
+
* float.abs
|
442
|
+
*
|
443
|
+
* From the GMP Manual:
|
444
|
+
*
|
445
|
+
* Returns the absolute value of +float+.
|
446
|
+
*/
|
447
|
+
/*
|
448
|
+
* Document-method: abs!
|
449
|
+
*
|
450
|
+
* call-seq:
|
451
|
+
* float.abs!
|
452
|
+
*
|
453
|
+
* Sets +float+ to the absolute value of +float+.
|
454
|
+
*/
|
455
|
+
DEFUN_FLOAT2FLOAT(abs,mpf_abs)
|
456
|
+
|
457
|
+
|
458
|
+
/**********************************************************************
|
459
|
+
* Float Comparison *
|
460
|
+
**********************************************************************/
|
461
|
+
|
462
|
+
int mpf_cmp_value(MP_FLOAT *self_val, VALUE arg)
|
463
|
+
{
|
464
|
+
MP_FLOAT *arg_val;
|
465
|
+
int result;
|
466
|
+
|
467
|
+
if (GMPF_P(arg)) {
|
468
|
+
mpf_get_struct(arg,arg_val);
|
469
|
+
return mpf_cmp (self_val, arg_val);
|
470
|
+
} else {
|
471
|
+
mpf_temp_init(arg_val, mpf_get_prec (self_val));
|
472
|
+
mpf_set_value (arg_val, arg);
|
473
|
+
result = mpf_cmp (self_val, arg_val);
|
474
|
+
mpf_temp_free(arg_val);
|
475
|
+
return result;
|
476
|
+
}
|
477
|
+
}
|
478
|
+
|
479
|
+
/* what does really "equal" mean ? it's not obvious */
|
480
|
+
VALUE r_gmpf_eq(VALUE self, VALUE arg)
|
481
|
+
{
|
482
|
+
MP_FLOAT *self_val;
|
483
|
+
mpf_get_struct (self,self_val);
|
484
|
+
return (mpf_cmp_value(self_val, arg) == 0) ? Qtrue : Qfalse;
|
485
|
+
}
|
486
|
+
|
487
|
+
VALUE r_gmpf_cmp(VALUE self, VALUE arg)
|
488
|
+
{
|
489
|
+
MP_FLOAT *self_val;
|
490
|
+
int res;
|
491
|
+
mpf_get_struct(self,self_val);
|
492
|
+
res = mpf_cmp_value(self_val, arg);
|
493
|
+
if (res > 0)
|
494
|
+
return INT2FIX(1);
|
495
|
+
else if (res == 0)
|
496
|
+
return INT2FIX(0);
|
497
|
+
else
|
498
|
+
return INT2FIX(-1);
|
499
|
+
}
|
500
|
+
|
501
|
+
DEFUN_FLOAT_CMP(lt,<)
|
502
|
+
DEFUN_FLOAT_CMP(le,<=)
|
503
|
+
DEFUN_FLOAT_CMP(gt,>)
|
504
|
+
DEFUN_FLOAT_CMP(ge,>=)
|
505
|
+
|
506
|
+
|
507
|
+
/**********************************************************************
|
508
|
+
* _unsorted_ *
|
509
|
+
**********************************************************************/
|
510
|
+
|
511
|
+
DEFUN_FLOAT2FLOAT(floor,mpf_floor)
|
512
|
+
DEFUN_FLOAT2FLOAT(trunc,mpf_trunc)
|
513
|
+
DEFUN_FLOAT2FLOAT(ceil,mpf_ceil)
|
514
|
+
|
515
|
+
/*
|
516
|
+
* call-seq:
|
517
|
+
* float.sgn
|
518
|
+
*
|
519
|
+
* From the GMP Manual:
|
520
|
+
*
|
521
|
+
* Returns +1 if +float+ > 0, 0 if +float+ == 0, and -1 if +float+ < 0.
|
522
|
+
*/
|
523
|
+
VALUE r_gmpf_sgn(VALUE self)
|
524
|
+
{
|
525
|
+
MP_FLOAT *self_val;
|
526
|
+
mpf_get_struct(self, self_val);
|
527
|
+
return INT2FIX(mpf_sgn(self_val));
|
528
|
+
}
|
529
|
+
|
530
|
+
VALUE r_gmpf_get_prec(VALUE self)
|
531
|
+
{
|
532
|
+
MP_FLOAT *self_val;
|
533
|
+
mpf_get_struct(self, self_val);
|
534
|
+
return INT2NUM(mpf_get_prec(self_val));
|
535
|
+
}
|
536
|
+
|
537
|
+
|
538
|
+
void init_gmpf()
|
539
|
+
{
|
540
|
+
mGMP = rb_define_module("GMP");
|
541
|
+
// rb_define_module_function(mGMP, "Z", r_gmpmod_z, -1);
|
542
|
+
// rb_define_module_function(mGMP, "Q", r_gmpmod_q, -1);
|
543
|
+
rb_define_module_function(mGMP, "F", r_gmpmod_f, -1);
|
544
|
+
|
545
|
+
cGMP_F = rb_define_class_under (mGMP, "F", rb_cNumeric);
|
546
|
+
|
547
|
+
|
548
|
+
// Initializing, Assigning Floats
|
549
|
+
rb_define_singleton_method(cGMP_F, "new", r_gmpfsg_new, -1);
|
550
|
+
rb_define_method(cGMP_F, "initialize", r_gmpf_initialize, -1);
|
551
|
+
|
552
|
+
// Converting Floats
|
553
|
+
rb_define_method(cGMP_F, "to_s", r_gmpf_to_s, 0);
|
554
|
+
rb_define_method(cGMP_F, "to_d", r_gmpf_to_d, 0);
|
555
|
+
rb_define_alias(cGMP_F, "to_f", "to_d");
|
556
|
+
|
557
|
+
// Float Arithmetic
|
558
|
+
rb_define_method(cGMP_F, "+", r_gmpf_add, 1);
|
559
|
+
rb_define_method(cGMP_F, "-", r_gmpf_sub, 1);
|
560
|
+
rb_define_method(cGMP_F, "*", r_gmpf_mul, 1);
|
561
|
+
rb_define_method(cGMP_F, "/", r_gmpf_div, 1);
|
562
|
+
rb_define_method(cGMP_F, "-@", r_gmpf_neg, 0);
|
563
|
+
rb_define_method(cGMP_F, "neg!", r_gmpf_neg_self, 0);
|
564
|
+
rb_define_method(cGMP_F, "abs", r_gmpf_abs, 0);
|
565
|
+
rb_define_method(cGMP_F, "abs!", r_gmpf_abs_self, 0);
|
566
|
+
|
567
|
+
// Float Comparison
|
568
|
+
rb_define_method(cGMP_F, "<=>", r_gmpf_cmp, 1);
|
569
|
+
rb_define_method(cGMP_F, ">", r_gmpf_cmp_gt, 1);
|
570
|
+
rb_define_method(cGMP_F, ">=", r_gmpf_cmp_ge, 1);
|
571
|
+
rb_define_method(cGMP_F, "<", r_gmpf_cmp_lt, 1);
|
572
|
+
rb_define_method(cGMP_F, "<=", r_gmpf_cmp_le, 1);
|
573
|
+
rb_define_method(cGMP_F, "==", r_gmpf_eq, 1);
|
574
|
+
|
575
|
+
// _unsorted_
|
576
|
+
rb_define_method(cGMP_F, "floor", r_gmpf_floor, 0);
|
577
|
+
rb_define_method(cGMP_F, "floor!", r_gmpf_floor_self, 0);
|
578
|
+
rb_define_method(cGMP_F, "ceil", r_gmpf_ceil, 0);
|
579
|
+
rb_define_method(cGMP_F, "ceil!", r_gmpf_ceil_self, 0);
|
580
|
+
rb_define_method(cGMP_F, "trunc", r_gmpf_trunc, 0);
|
581
|
+
rb_define_method(cGMP_F, "trunc!", r_gmpf_trunc_self, 0);
|
582
|
+
rb_define_method(cGMP_F, "sgn", r_gmpf_sgn, 0);
|
583
|
+
rb_define_method(cGMP_F, "prec", r_gmpf_get_prec, 0);
|
584
|
+
}
|