gmp 0.5.3 → 0.5.23
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +19 -0
- data/FEATURES.html +393 -0
- data/README.rdoc +64 -32
- data/ext/gmp.c +5 -55
- data/ext/gmpf.c +300 -179
- data/ext/gmpq.c +81 -111
- data/ext/gmprandstate.c +30 -0
- data/ext/gmpz.c +543 -424
- data/ext/gmpz.h +0 -8
- data/ext/ruby_gmp.h +14 -20
- data/manual.pdf +0 -0
- data/manual.tex +56 -11
- data/test/gmp_tgcd.rb +126 -0
- data/test/mpfr_tconst_euler.rb +36 -0
- data/test/tc_mpfr_functions.rb +48 -17
- data/test/tc_q.rb +80 -0
- data/test/tc_q_basic.rb +2 -2
- data/test/tc_z.rb +46 -16
- data/test/tc_z_submul.rb +94 -0
- data/test/tc_z_to_dis.rb +69 -0
- data/test/unit_tests.rb +8 -5
- metadata +10 -9
- data/benchmark/gexpr +0 -0
- data/test/tc_z_to_d_to_i.rb +0 -24
- data/test/test-12.rb +0 -14
- data/test/test-19.rb +0 -13
data/ext/gmp.c
CHANGED
@@ -98,55 +98,6 @@ static VALUE r_gmpfsg_set_default_prec(VALUE klass, VALUE arg)
|
|
98
98
|
}
|
99
99
|
|
100
100
|
#ifdef MPFR
|
101
|
-
static VALUE r_gmpfsg_get_default_rounding_mode(VALUE klass)
|
102
|
-
{
|
103
|
-
(void)klass;
|
104
|
-
const char *rounding_string_val;
|
105
|
-
rounding_string_val = mpfr_print_rnd_mode (mpfr_get_default_rounding_mode ());
|
106
|
-
if ( rounding_string_val == NULL ) {
|
107
|
-
return Qnil;
|
108
|
-
}
|
109
|
-
else {
|
110
|
-
return rb_const_get (mGMP, rb_intern (rounding_string_val));
|
111
|
-
}
|
112
|
-
}
|
113
|
-
|
114
|
-
static VALUE r_gmpfsg_set_default_rounding_mode(VALUE klass, VALUE arg)
|
115
|
-
{
|
116
|
-
(void)klass;
|
117
|
-
VALUE mode;
|
118
|
-
if (GMPRND_P(arg)) {
|
119
|
-
mode = rb_funcall (arg, rb_intern("mode"), 0);
|
120
|
-
if (FIX2INT(mode) < 0 || FIX2INT(mode) > 3) {
|
121
|
-
rb_raise(rb_eRangeError, "rounding mode must be one of the rounding mode constants.");
|
122
|
-
}
|
123
|
-
} else {
|
124
|
-
rb_raise(rb_eTypeError, "rounding mode must be one of the rounding mode constants.");
|
125
|
-
}
|
126
|
-
|
127
|
-
switch (FIX2INT(mode)) {
|
128
|
-
case 0:
|
129
|
-
mpfr_set_default_rounding_mode (GMP_RNDN);
|
130
|
-
break;
|
131
|
-
case 1:
|
132
|
-
mpfr_set_default_rounding_mode (GMP_RNDZ);
|
133
|
-
break;
|
134
|
-
case 2:
|
135
|
-
mpfr_set_default_rounding_mode (GMP_RNDU);
|
136
|
-
break;
|
137
|
-
case 3:
|
138
|
-
mpfr_set_default_rounding_mode (GMP_RNDD);
|
139
|
-
break;
|
140
|
-
#if MPFR_VERSION_MAJOR>2
|
141
|
-
case 4:
|
142
|
-
mpfr_set_default_rounding_mode (MPFR_RNDA);
|
143
|
-
break;
|
144
|
-
#endif
|
145
|
-
}
|
146
|
-
|
147
|
-
return Qnil;
|
148
|
-
}
|
149
|
-
|
150
101
|
mp_rnd_t r_get_rounding_mode(VALUE rnd)
|
151
102
|
{
|
152
103
|
VALUE mode;
|
@@ -193,12 +144,13 @@ mp_rnd_t r_get_rounding_mode(VALUE rnd)
|
|
193
144
|
|
194
145
|
void Init_gmp() {
|
195
146
|
mGMP = rb_define_module("GMP");
|
196
|
-
rb_define_const(mGMP, "GMP_VERSION",
|
197
|
-
rb_define_const(mGMP, "GMP_CC",
|
198
|
-
rb_define_const(mGMP, "GMP_CFLAGS",
|
147
|
+
rb_define_const(mGMP, "GMP_VERSION", rb_str_new2(gmp_version));
|
148
|
+
rb_define_const(mGMP, "GMP_CC", rb_str_new2(__GMP_CC));
|
149
|
+
rb_define_const(mGMP, "GMP_CFLAGS", rb_str_new2(__GMP_CFLAGS));
|
199
150
|
rb_define_const(mGMP, "GMP_BITS_PER_LIMB", INT2FIX(mp_bits_per_limb));
|
151
|
+
rb_define_const(mGMP, "GMP_NUMB_MAX", ULONG2NUM(GMP_NUMB_MAX));
|
200
152
|
#ifdef MPFR
|
201
|
-
rb_define_const(mGMP, "MPFR_VERSION",
|
153
|
+
rb_define_const(mGMP, "MPFR_VERSION", rb_str_new2(MPFR_VERSION_STRING));
|
202
154
|
rb_define_const(mGMP, "MPFR_PREC_MIN", INT2FIX(MPFR_PREC_MIN));
|
203
155
|
rb_define_const(mGMP, "MPFR_PREC_MAX", INT2FIX(MPFR_PREC_MAX));
|
204
156
|
#endif /* MPFR */
|
@@ -220,8 +172,6 @@ void Init_gmp() {
|
|
220
172
|
rb_define_singleton_method (cGMP_F, "default_prec=", r_gmpfsg_set_default_prec, 1);
|
221
173
|
#ifdef MPFR
|
222
174
|
cGMP_Rnd = rb_define_class_under (mGMP, "Rnd", rb_cObject);
|
223
|
-
rb_define_singleton_method (cGMP_F, "default_rounding_mode", r_gmpfsg_get_default_rounding_mode, 0);
|
224
|
-
rb_define_singleton_method (cGMP_F, "default_rounding_mode=", r_gmpfsg_set_default_rounding_mode, 1);
|
225
175
|
init_gmprnd ();
|
226
176
|
#endif /* MPFR */
|
227
177
|
rb_define_method (cGMP_F, "coerce", r_gmpf_coerce, 1); // new method - testing
|
data/ext/gmpf.c
CHANGED
@@ -10,17 +10,6 @@
|
|
10
10
|
* Instances of this class can store variables of the type mpf_t. This class
|
11
11
|
* also contains many methods that act as the functions for mpf_t variables,
|
12
12
|
* as well as a few methods that attempt to make this library more Ruby-ish.
|
13
|
-
*
|
14
|
-
* The following list is just a simple checklist for me, really. A better
|
15
|
-
* reference should be found in the rdocs.
|
16
|
-
*
|
17
|
-
* Ruby method C Extension function GMP function
|
18
|
-
* to_d r_gmpf_to_d mpf_get_d
|
19
|
-
* to_s r_gmpf_to_s mpf_get_s
|
20
|
-
* + r_gmpf_add mpf_add
|
21
|
-
* - r_gmpf_sub mpf_sub
|
22
|
-
* * r_gmpf_mul mpf_mul
|
23
|
-
* / r_gmpf_div mpf_div
|
24
13
|
*/
|
25
14
|
|
26
15
|
/**********************************************************************
|
@@ -250,6 +239,12 @@ VALUE r_gmpmod_f(int argc, VALUE *argv, VALUE module)
|
|
250
239
|
* Converting Floats *
|
251
240
|
**********************************************************************/
|
252
241
|
|
242
|
+
/*
|
243
|
+
* call-seq:
|
244
|
+
* x.to_d
|
245
|
+
*
|
246
|
+
* Returns _x_ as a Float.
|
247
|
+
*/
|
253
248
|
VALUE r_gmpf_to_d(VALUE self)
|
254
249
|
{
|
255
250
|
MP_FLOAT *self_val;
|
@@ -260,12 +255,10 @@ VALUE r_gmpf_to_d(VALUE self)
|
|
260
255
|
|
261
256
|
#ifdef MPFR
|
262
257
|
/*
|
263
|
-
* Document-method: to_s
|
264
|
-
*
|
265
258
|
* call-seq:
|
266
|
-
*
|
259
|
+
* x.to_s
|
267
260
|
*
|
268
|
-
* Returns the decimal representation of
|
261
|
+
* Returns the decimal representation of _x_, as a String.
|
269
262
|
*/
|
270
263
|
VALUE r_gmpf_to_s(VALUE self)
|
271
264
|
{
|
@@ -301,12 +294,10 @@ VALUE r_gmpf_to_s(VALUE self)
|
|
301
294
|
}
|
302
295
|
#else
|
303
296
|
/*
|
304
|
-
* Document-method: to_s
|
305
|
-
*
|
306
297
|
* call-seq:
|
307
|
-
*
|
298
|
+
* x.to_s
|
308
299
|
*
|
309
|
-
* Returns the decimal representation of
|
300
|
+
* Returns the decimal representation of _x_, as a string.
|
310
301
|
*/
|
311
302
|
VALUE r_gmpf_to_s(VALUE self)
|
312
303
|
{
|
@@ -346,9 +337,9 @@ VALUE r_gmpf_to_s(VALUE self)
|
|
346
337
|
#ifndef MPFR
|
347
338
|
/*
|
348
339
|
* call-seq:
|
349
|
-
*
|
340
|
+
* x + y
|
350
341
|
*
|
351
|
-
* Returns the sum of
|
342
|
+
* Returns the sum of _x_ and _y_. _y_ must be an instance of:
|
352
343
|
* * GMP::Z
|
353
344
|
* * Fixnum
|
354
345
|
* * GMP::Q
|
@@ -404,9 +395,9 @@ VALUE r_gmpf_add(VALUE self, VALUE arg)
|
|
404
395
|
#else
|
405
396
|
/*
|
406
397
|
* call-seq:
|
407
|
-
*
|
398
|
+
* x + y
|
408
399
|
*
|
409
|
-
* Returns the sum of
|
400
|
+
* Returns the sum of _x_ and _y_. _y_ must be an instance of:
|
410
401
|
* * GMP::Z
|
411
402
|
* * Fixnum
|
412
403
|
* * GMP::Q
|
@@ -470,9 +461,9 @@ DEFUN_F_ZQXFBD2F(mul)
|
|
470
461
|
|
471
462
|
/*
|
472
463
|
* call-seq:
|
473
|
-
*
|
464
|
+
* x - y
|
474
465
|
*
|
475
|
-
* Subtracts
|
466
|
+
* Subtracts _y_ from _x_. _y_ must be an instance of:
|
476
467
|
* * GMP::Z
|
477
468
|
* * Fixnum
|
478
469
|
* * GMP::Q
|
@@ -528,9 +519,9 @@ VALUE r_gmpf_sub(VALUE self, VALUE arg)
|
|
528
519
|
|
529
520
|
/*
|
530
521
|
* call-seq:
|
531
|
-
*
|
522
|
+
* x * y
|
532
523
|
*
|
533
|
-
* Returns the product of
|
524
|
+
* Returns the product of _x_ and _y_. _y_ can be
|
534
525
|
* * GMP::Z
|
535
526
|
* * Fixnum
|
536
527
|
* * GMP::Q
|
@@ -544,7 +535,6 @@ VALUE r_gmpf_mul(VALUE self, VALUE arg)
|
|
544
535
|
MP_RAT *arg_val_q;
|
545
536
|
MP_INT *arg_val_z;
|
546
537
|
VALUE res;
|
547
|
-
//unsigned long prec;
|
548
538
|
mpfr_prec_t prec;
|
549
539
|
|
550
540
|
mpf_get_struct_prec (self, self_val, prec);
|
@@ -587,10 +577,10 @@ VALUE r_gmpf_mul(VALUE self, VALUE arg)
|
|
587
577
|
|
588
578
|
/*
|
589
579
|
* call-seq:
|
590
|
-
*
|
580
|
+
* x ** y
|
591
581
|
*
|
592
|
-
* Returns
|
593
|
-
* * Fixnum or Bignum
|
582
|
+
* Returns _x_ raised to the _y_ power. _y_ must be
|
583
|
+
* * an instance of Fixnum or Bignum
|
594
584
|
* * non-negative
|
595
585
|
*/
|
596
586
|
VALUE r_gmpf_pow(VALUE self, VALUE arg)
|
@@ -617,65 +607,11 @@ VALUE r_gmpf_pow(VALUE self, VALUE arg)
|
|
617
607
|
return res;
|
618
608
|
}
|
619
609
|
|
620
|
-
#ifdef MPFR
|
621
|
-
/*
|
622
|
-
* call-seq:
|
623
|
-
* float ** other
|
624
|
-
*
|
625
|
-
* Returns +float+ raised to the +other+ power. +other+ must be an instance of
|
626
|
-
* * Fixnum
|
627
|
-
* * Bignum
|
628
|
-
* * Float
|
629
|
-
* * GMP::Z
|
630
|
-
* * GMP::F
|
631
|
-
*/
|
632
|
-
/*VALUE r_gmpfr_pow(int argc, VALUE *argv, VALUE self)
|
633
|
-
{
|
634
|
-
MP_FLOAT *self_val, *res_val, *arg_val_f;
|
635
|
-
VALUE arg, rnd_mode, res_prec;
|
636
|
-
unsigned long arg_val, prec, res_prec_value;
|
637
|
-
mp_rnd_t rnd_mode_value;
|
638
|
-
MP_INT *arg_val_z;
|
639
|
-
VALUE res;
|
640
|
-
|
641
|
-
rb_scan_args (argc, argv, "12", &arg, &rnd_mode, &res_prec);
|
642
|
-
|
643
|
-
mpf_get_struct_prec (self, self_val, prec);
|
644
|
-
|
645
|
-
if (NIL_P (rnd_mode)) { rnd_mode_value = __gmp_default_rounding_mode; }
|
646
|
-
else { rnd_mode_value = r_get_rounding_mode(rnd_mode); }
|
647
|
-
if (NIL_P (res_prec)) { res_prec_value = prec; }
|
648
|
-
else { res_prec_value = FIX2INT (res_prec); }
|
649
|
-
mpf_make_struct_init (res, res_val, res_prec_value);
|
650
|
-
|
651
|
-
if (FIXNUM_P(arg)) {
|
652
|
-
mpfr_pow_ui(res_val, self_val, FIX2NUM(arg), rnd_mode_value);
|
653
|
-
} else if (BIGNUM_P(arg)) {
|
654
|
-
mpz_temp_from_bignum(arg_val_z, arg);
|
655
|
-
mpfr_pow_z (res_val, self_val, arg_val_z, rnd_mode_value);
|
656
|
-
mpz_temp_free(arg_val_z);
|
657
|
-
} else if (FLOAT_P(arg)) {
|
658
|
-
r_mpf_set_d (res_val, NUM2DBL(arg));
|
659
|
-
mpfr_pow (res_val, self_val, res_val, rnd_mode_value);
|
660
|
-
} else if (GMPZ_P(arg)) {
|
661
|
-
mpz_get_struct (arg, arg_val_z);
|
662
|
-
mpfr_pow_z (res_val, self_val, arg_val_z, rnd_mode_value);
|
663
|
-
} else if (GMPF_P(arg)) {
|
664
|
-
mpf_get_struct (arg, arg_val_f);
|
665
|
-
mpfr_pow (res_val, self_val, arg_val_f, rnd_mode_value);
|
666
|
-
} else {
|
667
|
-
typeerror(ZFXBD);
|
668
|
-
}
|
669
|
-
|
670
|
-
return res;
|
671
|
-
}*/
|
672
|
-
#endif
|
673
|
-
|
674
610
|
/*
|
675
611
|
* call-seq:
|
676
|
-
*
|
612
|
+
* x / y
|
677
613
|
*
|
678
|
-
* Divides
|
614
|
+
* Divides _x_ by _y_. _y_ can be
|
679
615
|
* * GMP::Z
|
680
616
|
* * Fixnum
|
681
617
|
* * GMP::Q
|
@@ -729,45 +665,93 @@ VALUE r_gmpf_div(VALUE self, VALUE arg)
|
|
729
665
|
return res;
|
730
666
|
}
|
731
667
|
|
668
|
+
#ifdef MPFR
|
669
|
+
/*
|
670
|
+
* call-seq:
|
671
|
+
* float ** other
|
672
|
+
*
|
673
|
+
* Returns _x_ raised to the _y_ power. _y_ must be an instance of
|
674
|
+
* * Fixnum
|
675
|
+
* * Bignum
|
676
|
+
* * Float
|
677
|
+
* * GMP::Z
|
678
|
+
* * GMP::F
|
679
|
+
*/
|
680
|
+
/*VALUE r_gmpfr_pow(int argc, VALUE *argv, VALUE self)
|
681
|
+
{
|
682
|
+
MP_FLOAT *self_val, *res_val, *arg_val_f;
|
683
|
+
VALUE arg, rnd_mode, res_prec;
|
684
|
+
unsigned long arg_val, prec, res_prec_value;
|
685
|
+
mp_rnd_t rnd_mode_value;
|
686
|
+
MP_INT *arg_val_z;
|
687
|
+
VALUE res;
|
688
|
+
|
689
|
+
rb_scan_args (argc, argv, "12", &arg, &rnd_mode, &res_prec);
|
690
|
+
|
691
|
+
mpf_get_struct_prec (self, self_val, prec);
|
692
|
+
|
693
|
+
if (NIL_P (rnd_mode)) { rnd_mode_value = __gmp_default_rounding_mode; }
|
694
|
+
else { rnd_mode_value = r_get_rounding_mode(rnd_mode); }
|
695
|
+
if (NIL_P (res_prec)) { res_prec_value = prec; }
|
696
|
+
else { res_prec_value = FIX2INT (res_prec); }
|
697
|
+
mpf_make_struct_init (res, res_val, res_prec_value);
|
698
|
+
|
699
|
+
if (FIXNUM_P(arg)) {
|
700
|
+
mpfr_pow_ui(res_val, self_val, FIX2NUM(arg), rnd_mode_value);
|
701
|
+
} else if (BIGNUM_P(arg)) {
|
702
|
+
mpz_temp_from_bignum(arg_val_z, arg);
|
703
|
+
mpfr_pow_z (res_val, self_val, arg_val_z, rnd_mode_value);
|
704
|
+
mpz_temp_free(arg_val_z);
|
705
|
+
} else if (FLOAT_P(arg)) {
|
706
|
+
r_mpf_set_d (res_val, NUM2DBL(arg));
|
707
|
+
mpfr_pow (res_val, self_val, res_val, rnd_mode_value);
|
708
|
+
} else if (GMPZ_P(arg)) {
|
709
|
+
mpz_get_struct (arg, arg_val_z);
|
710
|
+
mpfr_pow_z (res_val, self_val, arg_val_z, rnd_mode_value);
|
711
|
+
} else if (GMPF_P(arg)) {
|
712
|
+
mpf_get_struct (arg, arg_val_f);
|
713
|
+
mpfr_pow (res_val, self_val, arg_val_f, rnd_mode_value);
|
714
|
+
} else {
|
715
|
+
typeerror(ZFXBD);
|
716
|
+
}
|
732
717
|
|
718
|
+
return res;
|
719
|
+
}*/
|
720
|
+
#endif
|
733
721
|
|
734
722
|
/*
|
735
723
|
* Document-method: neg
|
736
724
|
*
|
737
725
|
* call-seq:
|
738
|
-
*
|
739
|
-
* -
|
726
|
+
* x.neg
|
727
|
+
* -x
|
740
728
|
*
|
741
|
-
*
|
742
|
-
*
|
743
|
-
* Returns -+float+.
|
729
|
+
* Returns -_x_.
|
744
730
|
*/
|
745
731
|
/*
|
746
732
|
* Document-method: neg!
|
747
733
|
*
|
748
734
|
* call-seq:
|
749
|
-
*
|
735
|
+
* x.neg!
|
750
736
|
*
|
751
|
-
* Sets
|
737
|
+
* Sets _x_ to -_x_.
|
752
738
|
*/
|
753
739
|
DEFUN_FLOAT2FLOAT(neg,mpf_neg)
|
754
740
|
/*
|
755
741
|
* Document-method: abs
|
756
742
|
*
|
757
743
|
* call-seq:
|
758
|
-
*
|
744
|
+
* x.abs
|
759
745
|
*
|
760
|
-
*
|
761
|
-
*
|
762
|
-
* Returns the absolute value of +float+.
|
746
|
+
* Returns the absolute value of _x_.
|
763
747
|
*/
|
764
748
|
/*
|
765
749
|
* Document-method: abs!
|
766
750
|
*
|
767
751
|
* call-seq:
|
768
|
-
*
|
752
|
+
* x.abs!
|
769
753
|
*
|
770
|
-
* Sets
|
754
|
+
* Sets _x_ to the absolute value of _x_.
|
771
755
|
*/
|
772
756
|
DEFUN_FLOAT2FLOAT(abs,mpf_abs)
|
773
757
|
|
@@ -793,7 +777,10 @@ int mpf_cmp_value(MP_FLOAT *self_val, VALUE arg)
|
|
793
777
|
}
|
794
778
|
}
|
795
779
|
|
796
|
-
/*
|
780
|
+
/*
|
781
|
+
* what does really "equal" mean ? it's not obvious
|
782
|
+
* Is this a note that I, SRR, put in here? It is now obvious to me...
|
783
|
+
*/
|
797
784
|
VALUE r_gmpf_eq(VALUE self, VALUE arg)
|
798
785
|
{
|
799
786
|
MP_FLOAT *self_val;
|
@@ -820,6 +807,28 @@ DEFUN_FLOAT_CMP(le,<=)
|
|
820
807
|
DEFUN_FLOAT_CMP(gt,>)
|
821
808
|
DEFUN_FLOAT_CMP(ge,>=)
|
822
809
|
|
810
|
+
/*
|
811
|
+
* call-seq:
|
812
|
+
* x.sgn
|
813
|
+
*
|
814
|
+
* Returns +1 if _x_ > 0, 0 if _x_ == 0, and -1 if _x_ < 0.
|
815
|
+
*/
|
816
|
+
VALUE r_gmpf_sgn(VALUE self)
|
817
|
+
{
|
818
|
+
MP_FLOAT *self_val;
|
819
|
+
mpf_get_struct (self, self_val);
|
820
|
+
return INT2FIX (mpf_sgn (self_val));
|
821
|
+
}
|
822
|
+
|
823
|
+
|
824
|
+
/**********************************************************************
|
825
|
+
* Miscellaneous Float Functions *
|
826
|
+
**********************************************************************/
|
827
|
+
|
828
|
+
DEFUN_FLOAT2FLOAT(floor,mpf_floor)
|
829
|
+
DEFUN_FLOAT2FLOAT(trunc,mpf_trunc)
|
830
|
+
DEFUN_FLOAT2FLOAT(ceil,mpf_ceil)
|
831
|
+
|
823
832
|
|
824
833
|
#ifdef MPFR
|
825
834
|
|
@@ -827,15 +836,14 @@ DEFUN_FLOAT_CMP(ge,>=)
|
|
827
836
|
VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
|
828
837
|
{ \
|
829
838
|
MP_FLOAT *self_val, *res_val; \
|
830
|
-
VALUE rnd_mode, res_prec;
|
839
|
+
VALUE rnd_mode, res_prec, res; \
|
831
840
|
mpfr_prec_t prec, res_prec_value; \
|
832
841
|
mp_rnd_t rnd_mode_val; \
|
833
|
-
VALUE res; \
|
834
|
-
\
|
835
|
-
rb_scan_args (argc, argv, "02", &rnd_mode, &res_prec); \
|
836
842
|
\
|
837
843
|
mpf_get_struct_prec (self, self_val, prec); \
|
838
|
-
|
844
|
+
\
|
845
|
+
rb_scan_args (argc, argv, "02", &rnd_mode, &res_prec); \
|
846
|
+
if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
|
839
847
|
else { rnd_mode_val = r_get_rounding_mode(rnd_mode); } \
|
840
848
|
if (NIL_P (res_prec)) { res_prec_value = prec; } \
|
841
849
|
else { res_prec_value = FIX2INT (res_prec); } \
|
@@ -845,7 +853,31 @@ VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
|
|
845
853
|
return res; \
|
846
854
|
}
|
847
855
|
|
848
|
-
#define
|
856
|
+
#define MPFR_DOUBLE_FUNCTION(name) \
|
857
|
+
VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
|
858
|
+
{ \
|
859
|
+
MP_FLOAT *self_val, *sin_val, *cos_val; \
|
860
|
+
VALUE rnd_mode, sin_prec, cos_prec, sinn, coss; \
|
861
|
+
mpfr_prec_t prec, sin_prec_val, cos_prec_val; \
|
862
|
+
mp_rnd_t rnd_mode_val; \
|
863
|
+
\
|
864
|
+
mpf_get_struct_prec (self, self_val, prec); \
|
865
|
+
\
|
866
|
+
rb_scan_args (argc, argv, "03", &rnd_mode, &sin_prec, &cos_prec); \
|
867
|
+
if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
|
868
|
+
else { rnd_mode_val = r_get_rounding_mode(rnd_mode); } \
|
869
|
+
if (NIL_P (sin_prec)) { sin_prec_val = prec; } \
|
870
|
+
else { sin_prec_val = FIX2INT (sin_prec); } \
|
871
|
+
if (NIL_P (cos_prec)) { cos_prec_val = sin_prec_val; } \
|
872
|
+
else { cos_prec_val = FIX2INT (cos_prec); } \
|
873
|
+
mpf_make_struct_init (sinn, sin_val, sin_prec_val); \
|
874
|
+
mpf_make_struct_init (coss, cos_val, cos_prec_val); \
|
875
|
+
mpfr_##name (sin_val, cos_val, self_val, rnd_mode_val); \
|
876
|
+
\
|
877
|
+
return rb_ary_new3(2, sinn, coss); \
|
878
|
+
}
|
879
|
+
|
880
|
+
#define MPFR_SINGLE_LONG_FUNCTION(name) \
|
849
881
|
VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
|
850
882
|
{ \
|
851
883
|
MP_FLOAT *self_val, *res_val; \
|
@@ -861,11 +893,35 @@ VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
|
|
861
893
|
if (NIL_P (res_prec)) { res_prec_value = prec; } \
|
862
894
|
else { res_prec_value = FIX2INT (res_prec); } \
|
863
895
|
mpf_make_struct_init (res, res_val, res_prec_value); \
|
864
|
-
mpfr_##name (res_val, arg1_val, self_val, __gmp_default_rounding_mode);
|
896
|
+
mpfr_##name (res_val, arg1_val, self_val, __gmp_default_rounding_mode); \
|
865
897
|
\
|
866
898
|
return res; \
|
867
899
|
}
|
868
900
|
|
901
|
+
#define MPFR_SINGLE_MPF_FUNCTION(name) \
|
902
|
+
VALUE r_gmpfr_##name(int argc, VALUE *argv, VALUE self) \
|
903
|
+
{ \
|
904
|
+
MP_FLOAT *self_val, *arg1_val, *res_val; \
|
905
|
+
VALUE arg1, rnd_mode, res_prec; \
|
906
|
+
mpfr_prec_t prec, arg1_prec, res_prec_value; \
|
907
|
+
VALUE res; \
|
908
|
+
mp_rnd_t rnd_mode_val; \
|
909
|
+
\
|
910
|
+
rb_scan_args (argc, argv, "12", &arg1, &rnd_mode, &res_prec); \
|
911
|
+
\
|
912
|
+
mpf_get_struct_prec (self, self_val, prec); \
|
913
|
+
if (!GMPF_P (arg1)) { typeerror(FD); } \
|
914
|
+
mpf_get_struct_prec (arg1, arg1_val, arg1_prec); \
|
915
|
+
if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
|
916
|
+
else { rnd_mode_val = r_get_rounding_mode(rnd_mode); } \
|
917
|
+
if (NIL_P (res_prec)) { res_prec_value = prec; } \
|
918
|
+
else { res_prec_value = FIX2INT (res_prec); } \
|
919
|
+
mpf_make_struct_init (res, res_val, res_prec_value); \
|
920
|
+
mpfr_##name (res_val, arg1_val, self_val, rnd_mode_val); \
|
921
|
+
\
|
922
|
+
return res; \
|
923
|
+
}
|
924
|
+
|
869
925
|
#define MPFR_SINGLE_BOOLEAN_FUNCTION(name) \
|
870
926
|
static VALUE r_gmpfr_##name(VALUE self) \
|
871
927
|
{ \
|
@@ -879,17 +935,26 @@ static VALUE r_gmpfr_##name(VALUE self) \
|
|
879
935
|
}
|
880
936
|
|
881
937
|
|
882
|
-
#define MPFR_CONST_FUNCTION(name)
|
883
|
-
VALUE r_gmpfrsg_##name()
|
884
|
-
{
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
|
892
|
-
|
938
|
+
#define MPFR_CONST_FUNCTION(name) \
|
939
|
+
VALUE r_gmpfrsg_##name(int argc, VALUE *argv, VALUE self) \
|
940
|
+
{ \
|
941
|
+
(void)self; \
|
942
|
+
MP_FLOAT *res_val; \
|
943
|
+
VALUE res; \
|
944
|
+
VALUE rnd_mode, prec; \
|
945
|
+
mp_rnd_t rnd_mode_val; \
|
946
|
+
mpfr_prec_t prec_val; \
|
947
|
+
\
|
948
|
+
rb_scan_args (argc, argv, "02", &rnd_mode, &prec); \
|
949
|
+
\
|
950
|
+
if (NIL_P (rnd_mode)) { rnd_mode_val = __gmp_default_rounding_mode; } \
|
951
|
+
else { rnd_mode_val = r_get_rounding_mode(rnd_mode); } \
|
952
|
+
if (NIL_P (prec)) { prec_val = mpfr_get_default_prec(); } \
|
953
|
+
else { prec_val = FIX2INT (prec); } \
|
954
|
+
mpf_make_struct_init (res, res_val, prec_val); \
|
955
|
+
mpfr_##name (res_val, rnd_mode_val); \
|
956
|
+
\
|
957
|
+
return res; \
|
893
958
|
}
|
894
959
|
|
895
960
|
MPFR_SINGLE_FUNCTION(sqrt)
|
@@ -905,18 +970,18 @@ MPFR_SINGLE_FUNCTION(exp10)
|
|
905
970
|
MPFR_SINGLE_FUNCTION(cos)
|
906
971
|
MPFR_SINGLE_FUNCTION(sin)
|
907
972
|
MPFR_SINGLE_FUNCTION(tan)
|
973
|
+
MPFR_DOUBLE_FUNCTION(sin_cos)
|
908
974
|
MPFR_SINGLE_FUNCTION(sec)
|
909
975
|
MPFR_SINGLE_FUNCTION(csc)
|
910
976
|
MPFR_SINGLE_FUNCTION(cot)
|
911
|
-
|
912
977
|
MPFR_SINGLE_FUNCTION(acos)
|
913
978
|
MPFR_SINGLE_FUNCTION(asin)
|
914
979
|
MPFR_SINGLE_FUNCTION(atan)
|
915
|
-
|
980
|
+
MPFR_SINGLE_MPF_FUNCTION(atan2)
|
916
981
|
MPFR_SINGLE_FUNCTION(cosh)
|
917
982
|
MPFR_SINGLE_FUNCTION(sinh)
|
918
983
|
MPFR_SINGLE_FUNCTION(tanh)
|
919
|
-
|
984
|
+
MPFR_DOUBLE_FUNCTION(sinh_cosh)
|
920
985
|
MPFR_SINGLE_FUNCTION(sech)
|
921
986
|
MPFR_SINGLE_FUNCTION(csch)
|
922
987
|
MPFR_SINGLE_FUNCTION(coth)
|
@@ -939,10 +1004,13 @@ MPFR_SINGLE_FUNCTION(erf)
|
|
939
1004
|
MPFR_SINGLE_FUNCTION(erfc)
|
940
1005
|
MPFR_SINGLE_FUNCTION(j0)
|
941
1006
|
MPFR_SINGLE_FUNCTION(j1)
|
942
|
-
|
1007
|
+
MPFR_SINGLE_LONG_FUNCTION(jn)
|
943
1008
|
MPFR_SINGLE_FUNCTION(y0)
|
944
1009
|
MPFR_SINGLE_FUNCTION(y1)
|
945
|
-
|
1010
|
+
MPFR_SINGLE_LONG_FUNCTION(yn)
|
1011
|
+
|
1012
|
+
MPFR_SINGLE_MPF_FUNCTION(agm)
|
1013
|
+
MPFR_SINGLE_MPF_FUNCTION(hypot)
|
946
1014
|
|
947
1015
|
MPFR_CONST_FUNCTION(const_log2)
|
948
1016
|
MPFR_CONST_FUNCTION(const_pi)
|
@@ -1010,32 +1078,84 @@ static VALUE r_gmpfr_pow(VALUE self, VALUE arg)
|
|
1010
1078
|
return res;
|
1011
1079
|
}
|
1012
1080
|
|
1013
|
-
#endif
|
1014
|
-
|
1015
|
-
|
1016
1081
|
/**********************************************************************
|
1017
|
-
*
|
1082
|
+
* Rounding Related Functions *
|
1018
1083
|
**********************************************************************/
|
1019
1084
|
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1085
|
+
VALUE r_gmpfsg_get_default_rounding_mode(VALUE klass)
|
1086
|
+
{
|
1087
|
+
(void)klass;
|
1088
|
+
const char *rounding_string_val;
|
1089
|
+
rounding_string_val = mpfr_print_rnd_mode (mpfr_get_default_rounding_mode ());
|
1090
|
+
if ( rounding_string_val == NULL ) {
|
1091
|
+
return Qnil;
|
1092
|
+
}
|
1093
|
+
else {
|
1094
|
+
return rb_const_get (mGMP, rb_intern (rounding_string_val));
|
1095
|
+
}
|
1096
|
+
}
|
1023
1097
|
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1098
|
+
VALUE r_gmpfsg_set_default_rounding_mode(VALUE klass, VALUE arg)
|
1099
|
+
{
|
1100
|
+
(void)klass;
|
1101
|
+
VALUE mode;
|
1102
|
+
if (GMPRND_P(arg)) {
|
1103
|
+
mode = rb_funcall (arg, rb_intern("mode"), 0);
|
1104
|
+
if (FIX2INT(mode) < 0 || FIX2INT(mode) > 3) {
|
1105
|
+
rb_raise(rb_eRangeError, "rounding mode must be one of the rounding mode constants.");
|
1106
|
+
}
|
1107
|
+
} else {
|
1108
|
+
rb_raise(rb_eTypeError, "rounding mode must be one of the rounding mode constants.");
|
1109
|
+
}
|
1110
|
+
|
1111
|
+
switch (FIX2INT(mode)) {
|
1112
|
+
case 0:
|
1113
|
+
mpfr_set_default_rounding_mode (GMP_RNDN); break;
|
1114
|
+
case 1:
|
1115
|
+
mpfr_set_default_rounding_mode (GMP_RNDZ); break;
|
1116
|
+
case 2:
|
1117
|
+
mpfr_set_default_rounding_mode (GMP_RNDU); break;
|
1118
|
+
case 3:
|
1119
|
+
mpfr_set_default_rounding_mode (GMP_RNDD); break;
|
1120
|
+
#if MPFR_VERSION_MAJOR>2
|
1121
|
+
case 4:
|
1122
|
+
mpfr_set_default_rounding_mode (MPFR_RNDA); break;
|
1123
|
+
#endif
|
1124
|
+
}
|
1125
|
+
|
1126
|
+
return Qnil;
|
1127
|
+
}
|
1128
|
+
|
1129
|
+
VALUE r_gmpf_can_round(VALUE self, VALUE err, VALUE rnd1, VALUE rnd2, VALUE prec)
|
1033
1130
|
{
|
1034
1131
|
MP_FLOAT *self_val;
|
1035
|
-
|
1036
|
-
|
1132
|
+
mp_exp_t err_val;
|
1133
|
+
mpfr_rnd_t rnd1_val, rnd2_val;
|
1134
|
+
mpfr_prec_t prec_val;
|
1135
|
+
|
1136
|
+
mpf_get_struct(self, self_val);
|
1137
|
+
if (FIXNUM_P(err)) {
|
1138
|
+
err_val = FIX2INT(err);
|
1139
|
+
} else {
|
1140
|
+
typeerror_as(X, "err");
|
1141
|
+
}
|
1142
|
+
rnd1_val = r_get_rounding_mode(rnd1);
|
1143
|
+
rnd2_val = r_get_rounding_mode(rnd2);
|
1144
|
+
prec_val = FIX2INT (prec);
|
1145
|
+
|
1146
|
+
if (mpfr_can_round (self_val, err_val, rnd1_val, rnd2_val, prec_val))
|
1147
|
+
return Qtrue;
|
1148
|
+
else
|
1149
|
+
return Qfalse;
|
1037
1150
|
}
|
1038
1151
|
|
1152
|
+
#endif
|
1153
|
+
|
1154
|
+
|
1155
|
+
/**********************************************************************
|
1156
|
+
* _unsorted_ *
|
1157
|
+
**********************************************************************/
|
1158
|
+
|
1039
1159
|
VALUE r_gmpf_get_prec(VALUE self)
|
1040
1160
|
{
|
1041
1161
|
MP_FLOAT *self_val;
|
@@ -1162,37 +1282,33 @@ void init_gmpf()
|
|
1162
1282
|
//"unordered", r_gmpfr_unordered_p
|
1163
1283
|
|
1164
1284
|
// Special Functions
|
1165
|
-
rb_define_method(cGMP_F, "log",
|
1166
|
-
rb_define_method(cGMP_F, "log2",
|
1167
|
-
rb_define_method(cGMP_F, "log10",
|
1168
|
-
rb_define_method(cGMP_F, "exp",
|
1169
|
-
rb_define_method(cGMP_F, "exp2",
|
1170
|
-
rb_define_method(cGMP_F, "exp10",
|
1171
|
-
rb_define_method(cGMP_F, "cos",
|
1172
|
-
rb_define_method(cGMP_F, "sin",
|
1173
|
-
rb_define_method(cGMP_F, "tan",
|
1174
|
-
|
1175
|
-
rb_define_method(cGMP_F, "sec",
|
1176
|
-
rb_define_method(cGMP_F, "csc",
|
1177
|
-
rb_define_method(cGMP_F, "cot",
|
1178
|
-
|
1179
|
-
rb_define_method(cGMP_F, "
|
1180
|
-
rb_define_method(cGMP_F, "
|
1181
|
-
rb_define_method(cGMP_F, "
|
1182
|
-
|
1183
|
-
|
1184
|
-
rb_define_method(cGMP_F, "
|
1185
|
-
rb_define_method(cGMP_F, "
|
1186
|
-
rb_define_method(cGMP_F, "
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
rb_define_method(cGMP_F, "
|
1191
|
-
rb_define_method(cGMP_F, "
|
1192
|
-
rb_define_method(cGMP_F, "coth", r_gmpfr_coth, -1);
|
1193
|
-
rb_define_method(cGMP_F, "acosh", r_gmpfr_acosh, -1);
|
1194
|
-
rb_define_method(cGMP_F, "asinh", r_gmpfr_asinh, -1);
|
1195
|
-
rb_define_method(cGMP_F, "atanh", r_gmpfr_atanh, -1);
|
1285
|
+
rb_define_method(cGMP_F, "log", r_gmpfr_log, -1);
|
1286
|
+
rb_define_method(cGMP_F, "log2", r_gmpfr_log2, -1);
|
1287
|
+
rb_define_method(cGMP_F, "log10", r_gmpfr_log10, -1);
|
1288
|
+
rb_define_method(cGMP_F, "exp", r_gmpfr_exp, -1);
|
1289
|
+
rb_define_method(cGMP_F, "exp2", r_gmpfr_exp2, -1);
|
1290
|
+
rb_define_method(cGMP_F, "exp10", r_gmpfr_exp10, -1);
|
1291
|
+
rb_define_method(cGMP_F, "cos", r_gmpfr_cos, -1);
|
1292
|
+
rb_define_method(cGMP_F, "sin", r_gmpfr_sin, -1);
|
1293
|
+
rb_define_method(cGMP_F, "tan", r_gmpfr_tan, -1);
|
1294
|
+
rb_define_method(cGMP_F, "sin_cos", r_gmpfr_sin_cos, -1);
|
1295
|
+
rb_define_method(cGMP_F, "sec", r_gmpfr_sec, -1);
|
1296
|
+
rb_define_method(cGMP_F, "csc", r_gmpfr_csc, -1);
|
1297
|
+
rb_define_method(cGMP_F, "cot", r_gmpfr_cot, -1);
|
1298
|
+
rb_define_method(cGMP_F, "acos", r_gmpfr_acos, -1);
|
1299
|
+
rb_define_method(cGMP_F, "asin", r_gmpfr_asin, -1);
|
1300
|
+
rb_define_method(cGMP_F, "atan", r_gmpfr_atan, -1);
|
1301
|
+
rb_define_method(cGMP_F, "atan2", r_gmpfr_atan2, -1);
|
1302
|
+
rb_define_method(cGMP_F, "cosh", r_gmpfr_cosh, -1);
|
1303
|
+
rb_define_method(cGMP_F, "sinh", r_gmpfr_sinh, -1);
|
1304
|
+
rb_define_method(cGMP_F, "tanh", r_gmpfr_tanh, -1);
|
1305
|
+
rb_define_method(cGMP_F, "sinh_cosh", r_gmpfr_sinh_cosh, -1);
|
1306
|
+
rb_define_method(cGMP_F, "sech", r_gmpfr_sech, -1);
|
1307
|
+
rb_define_method(cGMP_F, "csch", r_gmpfr_csch, -1);
|
1308
|
+
rb_define_method(cGMP_F, "coth", r_gmpfr_coth, -1);
|
1309
|
+
rb_define_method(cGMP_F, "acosh", r_gmpfr_acosh, -1);
|
1310
|
+
rb_define_method(cGMP_F, "asinh", r_gmpfr_asinh, -1);
|
1311
|
+
rb_define_method(cGMP_F, "atanh", r_gmpfr_atanh, -1);
|
1196
1312
|
|
1197
1313
|
// "fac", r_gmpfr_fac
|
1198
1314
|
|
@@ -1218,17 +1334,22 @@ void init_gmpf()
|
|
1218
1334
|
|
1219
1335
|
// "fma", r_gmpfr_fma
|
1220
1336
|
// "fms", r_gmpfr_fms
|
1221
|
-
|
1222
|
-
|
1337
|
+
rb_define_method(cGMP_F, "agm", r_gmpfr_agm, -1);
|
1338
|
+
rb_define_method(cGMP_F, "hypot", r_gmpfr_hypot, -1);
|
1223
1339
|
// "ai", r_gmpfr_ai !! 3.0.0
|
1224
1340
|
|
1225
|
-
rb_define_singleton_method(cGMP_F, "const_log2", r_gmpfrsg_const_log2,
|
1226
|
-
rb_define_singleton_method(cGMP_F, "const_pi", r_gmpfrsg_const_pi,
|
1227
|
-
rb_define_singleton_method(cGMP_F, "const_euler", r_gmpfrsg_const_euler,
|
1228
|
-
rb_define_singleton_method(cGMP_F, "const_catalan", r_gmpfrsg_const_catalan,
|
1341
|
+
rb_define_singleton_method(cGMP_F, "const_log2", r_gmpfrsg_const_log2, -1);
|
1342
|
+
rb_define_singleton_method(cGMP_F, "const_pi", r_gmpfrsg_const_pi, -1);
|
1343
|
+
rb_define_singleton_method(cGMP_F, "const_euler", r_gmpfrsg_const_euler, -1);
|
1344
|
+
rb_define_singleton_method(cGMP_F, "const_catalan", r_gmpfrsg_const_catalan, -1);
|
1229
1345
|
|
1230
1346
|
// Integer and Remainder Related Functions
|
1231
1347
|
// "integer?", r_gmpfr_integer_p
|
1348
|
+
|
1349
|
+
// Rounding Related Functions
|
1350
|
+
rb_define_singleton_method (cGMP_F, "default_rounding_mode", r_gmpfsg_get_default_rounding_mode, 0);
|
1351
|
+
rb_define_singleton_method (cGMP_F, "default_rounding_mode=", r_gmpfsg_set_default_rounding_mode, 1);
|
1352
|
+
rb_define_method(cGMP_F, "can_round?", r_gmpf_can_round, 4);
|
1232
1353
|
#endif /* MPFR */
|
1233
1354
|
|
1234
1355
|
// _unsorted_
|