gmp 0.4.1 → 0.4.3

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 CHANGED
@@ -1,6 +1,20 @@
1
+ 0.4.3:
2
+ * Support for MPFR on Windows introduced. gmp-x86-mswin32 gem should be used.
3
+ * Removed compilation warnings when using MPFR
4
+ * Added constants GMP::GMP_CC, GMP::GMP_CFLAGS, and GMP::GMP_BITS_PER_LIMB.
5
+ * Added constant GMP::MPFR_VERSION.
6
+ * Added MPFR rounding constants. These will be changed soon though.
7
+ * Added MPFR tests adapted straight from the MPFR library, just tsqrt so far.
8
+ * Added 3x MPFR functions: sec(), csc(), cot().
9
+ * Added function existence tests from
10
+ * Unit test results: 78 tests, 1025 assertions, 0 failures, 0 errors
11
+ * Unit test results: 72 tests, 593 assertions, 0 failures, 0 errors (w/o MPFR)
12
+
1
13
  0.4.1:
2
14
  * Fixed some gem dates
15
+ * Fixed gmp.so in x86-mswin32 gem
3
16
  * Added urandomm(), documentation, and tests.
17
+ * Unit test results: 70 tests, 577 assertions, 0 failures, 0 errors
4
18
 
5
19
  0.4.0:
6
20
  * Support for Windows introduced. gmp-x86-mswin32 gem should be used.
@@ -63,7 +63,8 @@ by me: gmp gem 0.4.0 on:
63
63
  | | (MRI) Ruby 1.9.1 | |
64
64
  +-------------------------------------+-------------------+-----------+
65
65
 
66
- <b>Note:</b> To get this running on Mac OS X (32-bit), I compiled GMP 4.3.1 with:
66
+ <b>Note:</b> To get this running on Mac OS X (32-bit), I compiled GMP 4.3.1
67
+ with:
67
68
  ./configure ABI=32 --disable-dependency-tracking
68
69
 
69
70
  =Authors
@@ -71,9 +72,25 @@ by me: gmp gem 0.4.0 on:
71
72
  * Tomasz Wegrzanowski
72
73
  * srawlins
73
74
 
75
+ =Constants
76
+
77
+ The GMP module includes the following constants. Mathematical constants, such
78
+ as pi, are defined under class methods of GMP::F, listed below.
79
+
80
+ GMP::GMP_VERSION #=> A string like "5.0.1"
81
+ GMP::GMP_CC #=> The compiler used to compile GMP
82
+ GMP::GMP_CFLAGS #=> The CFLAGS used to compile GMP
83
+ GMP::GMP_BITS_PER_LIMB #=> The number of bits per limb
84
+ (if MPFR is available)
85
+ GMP::MPFR_VERSION #=> A string like "2.4.2"
86
+ GMP::GMP_RNDN #=> The constant representing "round to nearest"
87
+ GMP::GMP_RNDZ #=> The constant representing "round toward zero"
88
+ GMP::GMP_RNDU #=> The constant representing "round toward plus infinity"
89
+ GMP::GMP_RNDD #=> The constant representing "round toward minus infinity"
90
+
74
91
  =Classes
75
92
 
76
- The module GMP is provided with following classes:
93
+ The GMP module is provided with following classes:
77
94
  * GMP::Z - infinite precision integer numbers
78
95
  * GMP::Q - infinite precision rational numbers
79
96
  * GMP::F - arbitrary precision floating point numbers
@@ -190,19 +207,39 @@ You can also call them as:
190
207
  prec get precision
191
208
  floor,ceil,trunc nearest integer, GMP::F is returned, not GMP::Z
192
209
  floor!,ceil!,trunc! in-place nearest integer
193
- GMP::F (only if MPFR is available)
194
- exp e^object
195
- expm1 the same as (object.exp) - 1, with better
196
- precision
210
+ GMP::RandState
211
+ seed(integer) seed the generator with a Fixnum or GMP::Z
212
+ urandomb(fixnum) get uniformly distributed random number between 0
213
+ and 2^fixnum-1, inclusive
214
+ urandomm(integer) get uniformly distributed random number between 0
215
+ and integer-1, inclusive
216
+ GMP (timing functions for GMPbench (0.2))
217
+ cputime milliseconds of cpu time since Ruby start
218
+ time times the execution of a block
219
+
220
+ *only if MPFR is available*
221
+ class methods of GMP::F
222
+ const_log2 returns the natural log of 2
223
+ const_pi returns pi
224
+ const_euler returns euler
225
+ const_catalan returns catalan
226
+ GMP::F
227
+ sqrt square root of the object
228
+ ** power
197
229
  log natural logarithm of object
198
230
  log2 binary logarithm of object
199
231
  log10 decimal logarithm of object
232
+ exp e^object
200
233
  log1p the same as (object + 1).log, with better
201
234
  precision
202
- sqrt square root of the object
235
+ expm1 the same as (object.exp) - 1, with better
236
+ precision
203
237
  cos \
204
238
  sin |
205
239
  tan |
240
+ sec |
241
+ csc |
242
+ cot |
206
243
  acos |
207
244
  asin |
208
245
  atan | trigonometric functions
@@ -216,14 +253,9 @@ You can also call them as:
216
253
  infinite? | type of floating point number
217
254
  finite? |
218
255
  number? /
219
- ** power
220
256
  GMP::RandState
221
- seed(integer) seed the generator with a Fixnum or GMP::Z
222
- urandomb(fixnum) get uniformly distributed random number between 0
223
- and 2^fixnum-1, inclusive
224
- GMP (timing functions for GMPbench (0.2))
225
- cputime milliseconds of cpu time since Ruby start
226
- time times the execution of a block
257
+ mpfr_urandomb(fixnum) get uniformly distributed random floating-point
258
+ number within 0 <= rop < 1
227
259
 
228
260
 
229
261
  =Testing
@@ -251,8 +283,9 @@ If there is no explicit precision, highest precision of all GMP::F arguments is
251
283
  used. That doesn't ensure that result will be exact. For details, consult any
252
284
  paper about floating point arithmetics.
253
285
 
254
- Default precision can be explicitely set by passing 0 to GMP::F.new(). In
255
- particular, you can set precision of copy of GMP::F object by:
286
+ Default precision can be explicitely set by passing 0 as the second argument
287
+ for to GMP::F.new(). In particular, you can set precision of copy of GMP::F
288
+ object by:
256
289
  new_obj = GMP::F.new(old_obj, 0)
257
290
 
258
291
  Precision argument, and default_precision will be rounded up to whatever GMP
@@ -331,7 +364,6 @@ These are inherited from Tomasz. I will go through these and see which are
331
364
  still relevant.
332
365
 
333
366
  * mpz_fits_* and 31 vs. 32 integer variables
334
- * all appropriate module and class methods if there are any to add
335
367
  * fix all sign issues (don't know what these are)
336
368
  * floats with precision control
337
369
  * to_s vs. inspect
data/ext/gmp.c CHANGED
@@ -121,6 +121,51 @@ static VALUE r_gmpfsg_set_default_prec(VALUE klass, VALUE arg)
121
121
  return Qnil;
122
122
  }
123
123
 
124
+ #ifdef MPFR
125
+ static VALUE r_gmpfsg_get_default_rounding_mode(VALUE klass)
126
+ {
127
+ (void)klass;
128
+ const char *rounding_string_val;
129
+ VALUE rounding_string;
130
+ ID method_to_sym = rb_intern("to_sym");
131
+ rounding_string_val = mpfr_print_rnd_mode (mpfr_get_default_rounding_mode ());
132
+ rounding_string = rb_str_new2 (rounding_string_val);
133
+ /*return rb_const_get (mGMP, rb_intern (rounding_string));*/
134
+ return rb_funcall (rounding_string, method_to_sym, 0);
135
+ }
136
+
137
+ static VALUE r_gmpfsg_set_default_rounding_mode(VALUE klass, VALUE arg)
138
+ {
139
+ (void)klass;
140
+ int arg_val;
141
+ if (FIXNUM_P(arg)) {
142
+ arg_val = FIX2INT(arg);
143
+ if (arg_val < 0 || arg_val > 3) {
144
+ rb_raise(rb_eRangeError, "rounding mode must be one of the rounding mode constants.");
145
+ }
146
+ } else {
147
+ rb_raise(rb_eTypeError, "rounding mode must be one of the rounding mode constants.");
148
+ }
149
+
150
+ switch (arg_val) {
151
+ case 0:
152
+ mpfr_set_default_rounding_mode (GMP_RNDN);
153
+ break;
154
+ case 1:
155
+ mpfr_set_default_rounding_mode (GMP_RNDZ);
156
+ break;
157
+ case 2:
158
+ mpfr_set_default_rounding_mode (GMP_RNDU);
159
+ break;
160
+ case 3:
161
+ mpfr_set_default_rounding_mode (GMP_RNDD);
162
+ break;
163
+ }
164
+
165
+ return Qnil;
166
+ }
167
+ #endif /* MPFR */
168
+
124
169
  #include "gmpf.h"
125
170
  #include "gmpq.h"
126
171
  /* #include "gmpz.h" */
@@ -135,6 +180,18 @@ static VALUE r_gmpfsg_set_default_prec(VALUE klass, VALUE arg)
135
180
  void Init_gmp() {
136
181
  mGMP = rb_define_module("GMP");
137
182
  rb_define_const(mGMP, "GMP_VERSION", rb_str_new2(gmp_version));
183
+ rb_define_const(mGMP, "GMP_CC", rb_str_new2(__GMP_CC));
184
+ rb_define_const(mGMP, "GMP_CFLAGS", rb_str_new2(__GMP_CFLAGS));
185
+ rb_define_const(mGMP, "GMP_BITS_PER_LIMB", INT2FIX(mp_bits_per_limb));
186
+ #ifdef MPFR
187
+ rb_define_const(mGMP, "MPFR_VERSION", rb_str_new2(MPFR_VERSION_STRING));
188
+ rb_define_const(mGMP, "MPFR_PREC_MIN", INT2FIX(MPFR_PREC_MIN));
189
+ rb_define_const(mGMP, "MPFR_PREC_MAX", INT2FIX(MPFR_PREC_MAX));
190
+ rb_define_const(mGMP, "GMP_RNDN", INT2FIX(0));
191
+ rb_define_const(mGMP, "GMP_RNDZ", INT2FIX(1));
192
+ rb_define_const(mGMP, "GMP_RNDU", INT2FIX(2));
193
+ rb_define_const(mGMP, "GMP_RNDD", INT2FIX(3));
194
+ #endif /* MPFR */
138
195
 
139
196
  cGMP_Z = rb_define_class_under(mGMP, "Z", rb_cInteger);
140
197
  init_gmpz();
@@ -149,8 +206,12 @@ void Init_gmp() {
149
206
 
150
207
  cGMP_F = rb_define_class_under (mGMP, "F", rb_cNumeric);
151
208
  init_gmpf();
152
- rb_define_singleton_method(cGMP_F, "default_prec", r_gmpfsg_get_default_prec, 0);
153
- rb_define_singleton_method(cGMP_F, "default_prec=", r_gmpfsg_set_default_prec, 1);
209
+ rb_define_singleton_method (cGMP_F, "default_prec", r_gmpfsg_get_default_prec, 0);
210
+ rb_define_singleton_method (cGMP_F, "default_prec=", r_gmpfsg_set_default_prec, 1);
211
+ #ifdef MPFR
212
+ rb_define_singleton_method (cGMP_F, "default_rounding_mode", r_gmpfsg_get_default_rounding_mode, 0);
213
+ rb_define_singleton_method (cGMP_F, "default_rounding_mode=", r_gmpfsg_set_default_rounding_mode, 1);
214
+ #endif /* MPFR */
154
215
  rb_define_method(cGMP_F, "coerce", r_gmpf_coerce, 1); // new method - testing
155
216
 
156
217
  /* rb_define_method(cGMP_F, "cmpabs", r_gmpf_cmpabs, 1);*/
@@ -160,34 +221,6 @@ void Init_gmp() {
160
221
 
161
222
  init_gmpbench_timing();
162
223
 
163
- #ifdef MPFR
164
- rb_define_method(cGMP_F, "exp", r_gmpfr_exp, 0);
165
- rb_define_method(cGMP_F, "log", r_gmpfr_log, 0);
166
- rb_define_method(cGMP_F, "sqrt", r_gmpfr_sqrt, 0);
167
- rb_define_method(cGMP_F, "cos", r_gmpfr_cos, 0);
168
- rb_define_method(cGMP_F, "sin", r_gmpfr_sin, 0);
169
- rb_define_method(cGMP_F, "tan", r_gmpfr_tan, 0);
170
- rb_define_method(cGMP_F, "acos", r_gmpfr_acos, 0);
171
- rb_define_method(cGMP_F, "asin", r_gmpfr_asin, 0);
172
- rb_define_method(cGMP_F, "atan", r_gmpfr_atan, 0);
173
- rb_define_method(cGMP_F, "cosh", r_gmpfr_cosh, 0);
174
- rb_define_method(cGMP_F, "sinh", r_gmpfr_sinh, 0);
175
- rb_define_method(cGMP_F, "tanh", r_gmpfr_tanh, 0);
176
- rb_define_method(cGMP_F, "acosh", r_gmpfr_acosh, 0);
177
- rb_define_method(cGMP_F, "asinh", r_gmpfr_asinh, 0);
178
- rb_define_method(cGMP_F, "atanh", r_gmpfr_atanh, 0);
179
- rb_define_method(cGMP_F, "log1p", r_gmpfr_log1p, 0);
180
- rb_define_method(cGMP_F, "expm1", r_gmpfr_expm1, 0);
181
- rb_define_method(cGMP_F, "log2", r_gmpfr_log2, 0);
182
- rb_define_method(cGMP_F, "log10", r_gmpfr_log10, 0);
183
-
184
- rb_define_method(cGMP_F, "nan?", r_gmpfr_nan_p, 0);
185
- rb_define_method(cGMP_F, "infinite?", r_gmpfr_inf_p, 0);
186
- rb_define_method(cGMP_F, "finite?", r_gmpfr_fin_p, 0);
187
- rb_define_method(cGMP_F, "number?", r_gmpfr_number_p, 0);
188
-
189
- rb_define_method(cGMP_F, "**", r_gmpfr_pow, 1);
190
- #endif /* MPFR */
191
224
  // more
192
225
 
193
226
  REGISTER_TAKEOVER(and, "&", "old_and")
data/ext/gmpf.c CHANGED
@@ -105,7 +105,7 @@ VALUE r_gmpf_initialize(int argc, VALUE *argv, VALUE self)
105
105
  else
106
106
  rb_raise(rb_eRangeError, "prec must be non-negative");
107
107
  } else {
108
- rb_raise(rb_eTypeError, "prec must be FixNum");
108
+ rb_raise(rb_eTypeError, "prec must be a Fixnum");
109
109
  }
110
110
  } else if (GMPF_P(arg)) {
111
111
  mpf_get_struct (arg, arg_val_f);
@@ -515,6 +515,166 @@ DEFUN_FLOAT_CMP(gt,>)
515
515
  DEFUN_FLOAT_CMP(ge,>=)
516
516
 
517
517
 
518
+ #ifdef MPFR
519
+
520
+ #define MPFR_SINGLE_FUNCTION(name) \
521
+ VALUE r_gmpfr_##name(VALUE self) \
522
+ { \
523
+ MP_FLOAT *self_val, *res_val; \
524
+ unsigned long prec; \
525
+ VALUE res; \
526
+ \
527
+ mpf_get_struct_prec (self, self_val, prec); \
528
+ mpf_make_struct_init (res, res_val, prec); \
529
+ mpfr_##name (res_val, self_val, __gmp_default_rounding_mode); \
530
+ \
531
+ return res; \
532
+ }
533
+
534
+ #define MPFR_CONST_FUNCTION(name) \
535
+ VALUE r_gmpfrsg_##name() \
536
+ { \
537
+ MP_FLOAT *res_val; \
538
+ VALUE res; \
539
+ \
540
+ mpf_make_struct (res, res_val); \
541
+ mpf_init (res_val); \
542
+ mpfr_##name (res_val, __gmp_default_rounding_mode); \
543
+ \
544
+ return res; \
545
+ }
546
+
547
+ MPFR_SINGLE_FUNCTION(sqrt)
548
+
549
+ MPFR_SINGLE_FUNCTION(log)
550
+ MPFR_SINGLE_FUNCTION(log2)
551
+ MPFR_SINGLE_FUNCTION(log10)
552
+ MPFR_SINGLE_FUNCTION(exp)
553
+
554
+ MPFR_SINGLE_FUNCTION(cos)
555
+ MPFR_SINGLE_FUNCTION(sin)
556
+ MPFR_SINGLE_FUNCTION(tan)
557
+ MPFR_SINGLE_FUNCTION(sec)
558
+ MPFR_SINGLE_FUNCTION(csc)
559
+ MPFR_SINGLE_FUNCTION(cot)
560
+
561
+ MPFR_SINGLE_FUNCTION(acos)
562
+ MPFR_SINGLE_FUNCTION(asin)
563
+ MPFR_SINGLE_FUNCTION(atan)
564
+
565
+ MPFR_SINGLE_FUNCTION(cosh)
566
+ MPFR_SINGLE_FUNCTION(sinh)
567
+ MPFR_SINGLE_FUNCTION(tanh)
568
+
569
+ MPFR_SINGLE_FUNCTION(acosh)
570
+ MPFR_SINGLE_FUNCTION(asinh)
571
+ MPFR_SINGLE_FUNCTION(atanh)
572
+
573
+ MPFR_SINGLE_FUNCTION(log1p)
574
+ MPFR_SINGLE_FUNCTION(expm1)
575
+
576
+ MPFR_CONST_FUNCTION(const_log2)
577
+ MPFR_CONST_FUNCTION(const_pi)
578
+ MPFR_CONST_FUNCTION(const_euler)
579
+ MPFR_CONST_FUNCTION(const_catalan)
580
+
581
+ static VALUE r_gmpfr_nan_p(VALUE self)
582
+ {
583
+ MP_FLOAT *self_val;
584
+
585
+ mpf_get_struct(self, self_val);
586
+ if (mpfr_nan_p(self_val)) {
587
+ return Qtrue;
588
+ }
589
+ else {
590
+ return Qfalse;
591
+ }
592
+ }
593
+
594
+ static VALUE r_gmpfr_inf_p(VALUE self)
595
+ {
596
+ MP_FLOAT *self_val;
597
+
598
+ mpf_get_struct(self, self_val);
599
+ if (mpfr_inf_p(self_val)) {
600
+ return Qtrue;
601
+ }
602
+ else {
603
+ return Qfalse;
604
+ }
605
+ }
606
+
607
+ static VALUE r_gmpfr_fin_p(VALUE self)
608
+ {
609
+ if (r_gmpfr_inf_p(self)) {
610
+ return Qfalse;
611
+ }
612
+ else {
613
+ return Qtrue;
614
+ }
615
+ }
616
+
617
+ static VALUE r_gmpfr_number_p(VALUE self)
618
+ {
619
+ MP_FLOAT *self_val;
620
+
621
+ mpf_get_struct(self, self_val);
622
+ if (mpfr_number_p(self_val)) {
623
+ return Qtrue;
624
+ }
625
+ else {
626
+ return Qfalse;
627
+ }
628
+ }
629
+
630
+ static VALUE r_gmpfr_pow(VALUE self, VALUE arg)
631
+ {
632
+ MP_FLOAT *self_val, *res_val, *arg_val_f;
633
+ MP_RAT *arg_val_q;
634
+ MP_INT *arg_val_z;
635
+ unsigned long prec;
636
+ VALUE res;
637
+
638
+ mpf_get_struct_prec(self, self_val, prec);
639
+
640
+ if (GMPF_P(arg)) {
641
+ mpf_get_struct(arg, arg_val_f);
642
+ prec_max(prec, arg_val_f);
643
+ mpf_make_struct_init(res, res_val, prec);
644
+ mpfr_pow(res_val, self_val, arg_val_f, __gmp_default_rounding_mode);
645
+ } else {
646
+ mpf_make_struct_init(res, res_val, prec);
647
+
648
+ if (GMPZ_P(arg)) {
649
+ mpz_get_struct(arg, arg_val_z);
650
+ mpf_set_z(res_val, arg_val_z);
651
+ mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
652
+ } else if (GMPQ_P(arg)) {
653
+ mpq_get_struct(arg, arg_val_q);
654
+ mpf_set_q(res_val, arg_val_q);
655
+ mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
656
+ } else if (FLOAT_P(arg)) {
657
+ mpf_set_d(res_val, NUM2DBL(arg));
658
+ mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
659
+ } else if (FIXNUM_P(arg)) {
660
+ mpfr_pow_si(res_val, self_val, FIX2INT(arg), __gmp_default_rounding_mode);
661
+ } else if (BIGNUM_P(arg)) {
662
+ mpz_temp_from_bignum(arg_val_z, arg);
663
+ mpf_set_z(res_val, arg_val_z);
664
+ mpz_temp_free(arg_val_z);
665
+ mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
666
+ } else {
667
+ typeerror(ZQFXBD);
668
+ }
669
+
670
+ }
671
+
672
+ return res;
673
+ }
674
+
675
+ #endif
676
+
677
+
518
678
  /**********************************************************************
519
679
  * _unsorted_ *
520
680
  **********************************************************************/
@@ -549,8 +709,6 @@ VALUE r_gmpf_get_prec(VALUE self)
549
709
  void init_gmpf()
550
710
  {
551
711
  mGMP = rb_define_module("GMP");
552
- // rb_define_module_function(mGMP, "Z", r_gmpmod_z, -1);
553
- // rb_define_module_function(mGMP, "Q", r_gmpmod_q, -1);
554
712
  rb_define_module_function(mGMP, "F", r_gmpmod_f, -1);
555
713
 
556
714
  cGMP_F = rb_define_class_under (mGMP, "F", rb_cNumeric);
@@ -583,6 +741,52 @@ void init_gmpf()
583
741
  rb_define_method(cGMP_F, "<=", r_gmpf_cmp_le, 1);
584
742
  rb_define_method(cGMP_F, "==", r_gmpf_eq, 1);
585
743
 
744
+ #ifdef MPFR
745
+ // Basic Arithmetic Functions
746
+ rb_define_method(cGMP_F, "sqrt", r_gmpfr_sqrt, 0);
747
+
748
+ rb_define_method(cGMP_F, "**", r_gmpfr_pow, 1);
749
+
750
+ // Comparison Functions
751
+ rb_define_method(cGMP_F, "nan?", r_gmpfr_nan_p, 0);
752
+ rb_define_method(cGMP_F, "infinite?", r_gmpfr_inf_p, 0);
753
+ rb_define_method(cGMP_F, "finite?", r_gmpfr_fin_p, 0);
754
+ rb_define_method(cGMP_F, "number?", r_gmpfr_number_p, 0);
755
+
756
+ // Special Functions
757
+ rb_define_method(cGMP_F, "log", r_gmpfr_log, 0);
758
+ rb_define_method(cGMP_F, "log2", r_gmpfr_log2, 0);
759
+ rb_define_method(cGMP_F, "log10", r_gmpfr_log10, 0);
760
+ rb_define_method(cGMP_F, "exp", r_gmpfr_exp, 0);
761
+
762
+ rb_define_method(cGMP_F, "cos", r_gmpfr_cos, 0);
763
+ rb_define_method(cGMP_F, "sin", r_gmpfr_sin, 0);
764
+ rb_define_method(cGMP_F, "tan", r_gmpfr_tan, 0);
765
+ rb_define_method(cGMP_F, "sec", r_gmpfr_sec, 0);
766
+ rb_define_method(cGMP_F, "csc", r_gmpfr_csc, 0);
767
+ rb_define_method(cGMP_F, "cot", r_gmpfr_cot, 0);
768
+
769
+ rb_define_method(cGMP_F, "acos", r_gmpfr_acos, 0);
770
+ rb_define_method(cGMP_F, "asin", r_gmpfr_asin, 0);
771
+ rb_define_method(cGMP_F, "atan", r_gmpfr_atan, 0);
772
+
773
+ rb_define_method(cGMP_F, "cosh", r_gmpfr_cosh, 0);
774
+ rb_define_method(cGMP_F, "sinh", r_gmpfr_sinh, 0);
775
+ rb_define_method(cGMP_F, "tanh", r_gmpfr_tanh, 0);
776
+
777
+ rb_define_method(cGMP_F, "acosh", r_gmpfr_acosh, 0);
778
+ rb_define_method(cGMP_F, "asinh", r_gmpfr_asinh, 0);
779
+ rb_define_method(cGMP_F, "atanh", r_gmpfr_atanh, 0);
780
+
781
+ rb_define_method(cGMP_F, "log1p", r_gmpfr_log1p, 0);
782
+ rb_define_method(cGMP_F, "expm1", r_gmpfr_expm1, 0);
783
+
784
+ rb_define_singleton_method(cGMP_F, "const_log2", r_gmpfrsg_const_log2, 0);
785
+ rb_define_singleton_method(cGMP_F, "const_pi", r_gmpfrsg_const_pi, 0);
786
+ rb_define_singleton_method(cGMP_F, "const_euler", r_gmpfrsg_const_euler, 0);
787
+ rb_define_singleton_method(cGMP_F, "const_catalan", r_gmpfrsg_const_catalan, 0);
788
+ #endif /* MPFR */
789
+
586
790
  // _unsorted_
587
791
  rb_define_method(cGMP_F, "floor", r_gmpf_floor, 0);
588
792
  rb_define_method(cGMP_F, "floor!", r_gmpf_floor_self, 0);
data/ext/gmpf.h CHANGED
@@ -9,136 +9,4 @@
9
9
 
10
10
  #include <ruby_gmp.h>
11
11
 
12
- #ifdef MPFR
13
- #define MPFR_SINGLE_FUNCTION(name) \
14
- static VALUE r_gmpfr_##name(VALUE self) \
15
- { \
16
- MP_FLOAT *self_val, *res_val; \
17
- unsigned long prec; \
18
- VALUE res; \
19
- \
20
- mpf_get_struct_prec(self, self_val, prec); \
21
- mpf_make_struct_init(res, res_val, prec); \
22
- mpfr_##name(res_val, self_val, __gmp_default_rounding_mode); \
23
- \
24
- return res; \
25
- }
26
-
27
- MPFR_SINGLE_FUNCTION(log)
28
- MPFR_SINGLE_FUNCTION(exp)
29
- MPFR_SINGLE_FUNCTION(sqrt)
30
- MPFR_SINGLE_FUNCTION(cos)
31
- MPFR_SINGLE_FUNCTION(sin)
32
- MPFR_SINGLE_FUNCTION(tan)
33
- MPFR_SINGLE_FUNCTION(acos)
34
- MPFR_SINGLE_FUNCTION(asin)
35
- MPFR_SINGLE_FUNCTION(atan)
36
- MPFR_SINGLE_FUNCTION(cosh)
37
- MPFR_SINGLE_FUNCTION(sinh)
38
- MPFR_SINGLE_FUNCTION(tanh)
39
- MPFR_SINGLE_FUNCTION(acosh)
40
- MPFR_SINGLE_FUNCTION(asinh)
41
- MPFR_SINGLE_FUNCTION(atanh)
42
- MPFR_SINGLE_FUNCTION(log1p)
43
- MPFR_SINGLE_FUNCTION(expm1)
44
- MPFR_SINGLE_FUNCTION(log2)
45
- MPFR_SINGLE_FUNCTION(log10)
46
-
47
- static VALUE r_gmpfr_nan_p(VALUE self)
48
- {
49
- MP_FLOAT *self_val;
50
-
51
- mpf_get_struct(self, self_val);
52
- if (mpfr_nan_p(self_val)) {
53
- return Qtrue;
54
- }
55
- else {
56
- return Qfalse;
57
- }
58
- }
59
-
60
- static VALUE r_gmpfr_inf_p(VALUE self)
61
- {
62
- MP_FLOAT *self_val;
63
-
64
- mpf_get_struct(self, self_val);
65
- if (mpfr_inf_p(self_val)) {
66
- return Qtrue;
67
- }
68
- else {
69
- return Qfalse;
70
- }
71
- }
72
-
73
- static VALUE r_gmpfr_fin_p(VALUE self)
74
- {
75
- if (r_gmpfr_inf_p(self)) {
76
- return Qfalse;
77
- }
78
- else {
79
- return Qtrue;
80
- }
81
- }
82
-
83
- static VALUE r_gmpfr_number_p(VALUE self)
84
- {
85
- MP_FLOAT *self_val;
86
-
87
- mpf_get_struct(self, self_val);
88
- if (mpfr_number_p(self_val)) {
89
- return Qtrue;
90
- }
91
- else {
92
- return Qfalse;
93
- }
94
- }
95
-
96
- static VALUE r_gmpfr_pow(VALUE self, VALUE arg)
97
- {
98
- MP_FLOAT *self_val, *res_val, *arg_val_f;
99
- MP_RAT *arg_val_q;
100
- MP_INT *arg_val_z;
101
- unsigned long prec;
102
- VALUE res;
103
-
104
- mpf_get_struct_prec(self, self_val, prec);
105
-
106
- if (GMPF_P(arg)) {
107
- mpf_get_struct(arg, arg_val_f);
108
- prec_max(prec, arg_val_f);
109
- mpf_make_struct_init(res, res_val, prec);
110
- mpfr_pow(res_val, self_val, arg_val_f, __gmp_default_rounding_mode);
111
- } else {
112
- mpf_make_struct_init(res, res_val, prec);
113
-
114
- if (GMPZ_P(arg)) {
115
- mpz_get_struct(arg, arg_val_z);
116
- mpf_set_z(res_val, arg_val_z);
117
- mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
118
- } else if (GMPQ_P(arg)) {
119
- mpq_get_struct(arg, arg_val_q);
120
- mpf_set_q(res_val, arg_val_q);
121
- mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
122
- } else if (FLOAT_P(arg)) {
123
- mpf_set_d(res_val, FLT2DBL(arg));
124
- mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
125
- } else if (FIXNUM_P(arg)) {
126
- mpfr_pow_si(res_val, self_val, FIX2INT(arg), __gmp_default_rounding_mode);
127
- } else if (BIGNUM_P(arg)) {
128
- mpz_temp_from_bignum(arg_val_z, arg);
129
- mpf_set_z(res_val, arg_val_z);
130
- mpz_temp_free(arg_val_z);
131
- mpfr_pow(res_val, self_val, res_val, __gmp_default_rounding_mode);
132
- } else {
133
- typeerror(ZQFXBD);
134
- }
135
-
136
- }
137
-
138
- return res;
139
- }
140
-
141
- #endif
142
-
143
-
144
12
  #endif
@@ -205,12 +205,13 @@ VALUE r_gmprandstate_urandomb(VALUE self, VALUE arg)
205
205
 
206
206
  /*
207
207
  * call-seq:
208
- * rand_state.urandomm(fixnum)
208
+ * rand_state.urandomm(integer)
209
209
  *
210
210
  * From the GMP Manual:
211
211
  *
212
212
  * Generate a uniformly distributed random integer in the range 0 to
213
- * fixnum-1, inclusive.
213
+ * _integer-1_, inclusive. _integer_ can be an instance of GMP::Z,
214
+ * Fixnum, or Bignum
214
215
  */
215
216
  VALUE r_gmprandstate_urandomm(VALUE self, VALUE arg)
216
217
  {
@@ -241,6 +242,54 @@ VALUE r_gmprandstate_urandomm(VALUE self, VALUE arg)
241
242
  return res;
242
243
  }
243
244
 
245
+
246
+ #ifdef MPFR
247
+ /**********************************************************************
248
+ * MPFR Random Numbers *
249
+ **********************************************************************/
250
+
251
+ /*
252
+ * call-seq:
253
+ * rand_state.mpfr_urandomb()
254
+ *
255
+ * From the MPFR Manual:
256
+ *
257
+ * Generate a uniformly distributed random float in the interval 0 <= rop < 1.
258
+ */
259
+ VALUE r_gmprandstate_mpfr_urandomb(int argc, VALUE *argv, VALUE self)
260
+ {
261
+ MP_RANDSTATE *self_val;
262
+ MP_FLOAT *res_val;
263
+ VALUE res;
264
+ unsigned long prec = 0;
265
+
266
+ if (argc > 1)
267
+ rb_raise (rb_eArgError, "wrong # of arguments(%d for 0 or 1)", argc);
268
+
269
+ mprandstate_get_struct (self,self_val);
270
+
271
+ if (argc == 1) {
272
+ if (FIXNUM_P (argv[0])) {
273
+ if (FIX2INT (argv[0]) >= 0)
274
+ prec = FIX2INT (argv[0]);
275
+ else
276
+ rb_raise (rb_eRangeError, "prec must be non-negative");
277
+ } else {
278
+ rb_raise (rb_eTypeError, "prec must be a Fixnum");
279
+ }
280
+ }
281
+
282
+ mpf_make_struct (res, res_val);
283
+ if (prec == 0) { mpf_init (res_val); }
284
+ else { mpf_init2 (res_val, prec); }
285
+
286
+ mpfr_urandomb (res_val, self_val);
287
+
288
+ return res;
289
+ }
290
+ #endif /* MPFR */
291
+
292
+
244
293
  void init_gmprandstate()
245
294
  {
246
295
  mGMP = rb_define_module("GMP");
@@ -258,4 +307,9 @@ void init_gmprandstate()
258
307
  // Integer Random Numbers
259
308
  rb_define_method(cGMP_RandState, "urandomb", r_gmprandstate_urandomb, 1);
260
309
  rb_define_method(cGMP_RandState, "urandomm", r_gmprandstate_urandomm, 1);
310
+
311
+ #ifdef MPFR
312
+ // Float Random Numbers
313
+ rb_define_method(cGMP_RandState, "mpfr_urandomb", r_gmprandstate_mpfr_urandomb, -1);
314
+ #endif /* MPFR */
261
315
  }
@@ -207,6 +207,40 @@ extern VALUE r_gmpf_eq(VALUE self, VALUE arg);
207
207
  extern VALUE r_gmpf_cmp(VALUE self, VALUE arg);
208
208
  extern int mpf_cmp_value(MP_FLOAT *OP, VALUE arg);
209
209
 
210
+ // MPFR
211
+ #ifdef MPFR
212
+ extern VALUE r_gmpfr_sqrt(VALUE self);
213
+
214
+ extern VALUE r_gmpfr_log(VALUE self);
215
+ extern VALUE r_gmpfr_log2(VALUE self);
216
+ extern VALUE r_gmpfr_log10(VALUE self);
217
+ extern VALUE r_gmpfr_exp(VALUE self);
218
+
219
+ extern VALUE r_gmpfr_cos(VALUE self);
220
+ extern VALUE r_gmpfr_sin(VALUE self);
221
+ extern VALUE r_gmpfr_tan(VALUE self);
222
+ extern VALUE r_gmpfr_sec(VALUE self);
223
+ extern VALUE r_gmpfr_csc(VALUE self);
224
+ extern VALUE r_gmpfr_cot(VALUE self);
225
+
226
+ extern VALUE r_gmpfr_acos(VALUE self);
227
+ extern VALUE r_gmpfr_asin(VALUE self);
228
+ extern VALUE r_gmpfr_atan(VALUE self);
229
+
230
+ extern VALUE r_gmpfr_cosh(VALUE self);
231
+ extern VALUE r_gmpfr_sinh(VALUE self);
232
+ extern VALUE r_gmpfr_tanh(VALUE self);
233
+
234
+ extern VALUE r_gmpfr_acosh(VALUE self);
235
+ extern VALUE r_gmpfr_asinh(VALUE self);
236
+ extern VALUE r_gmpfr_atanh(VALUE self);
237
+
238
+ extern VALUE r_gmpfrsg_const_log2();
239
+ extern VALUE r_gmpfrsg_const_pi();
240
+ extern VALUE r_gmpfrsg_const_euler();
241
+ extern VALUE r_gmpfrsg_const_catalan();
242
+ #endif /* MPFR */
243
+
210
244
  // _unsorted_
211
245
  extern VALUE r_gmpf_sgn(VALUE self);
212
246
  extern VALUE r_gmpf_get_prec(VALUE self);
@@ -226,6 +260,11 @@ extern VALUE r_gmprandstate_seed(VALUE self, VALUE arg);
226
260
  extern VALUE r_gmprandstate_urandomb(VALUE self, VALUE arg);
227
261
  extern VALUE r_gmprandstate_urandomm(VALUE self, VALUE arg);
228
262
 
263
+ #ifdef MPFR
264
+ // Float Random Numbers
265
+ extern VALUE r_gmprandstate_mpfr_urandomb(int argc, VALUE *argv, VALUE self);
266
+ #endif /* MPFR */
267
+
229
268
 
230
269
  /* from gmpbench_timing.c */
231
270
 
data/manual.pdf CHANGED
Binary file
data/manual.tex CHANGED
@@ -28,8 +28,8 @@
28
28
  \huge{gmp} &\\
29
29
  \midrule[3pt]
30
30
  \multicolumn{2}{r}{\large{Ruby bindings to the GMP library}}\\
31
- \multicolumn{2}{r}{\large{Edition 0.4.1}}\\
32
- \multicolumn{2}{r}{\large{1 March 2010}}
31
+ \multicolumn{2}{r}{\large{Edition 0.4.3}}\\
32
+ \multicolumn{2}{r}{\large{8 March 2010}}
33
33
  \end{tabular}
34
34
 
35
35
  \vfill
@@ -41,7 +41,7 @@
41
41
  This manual describes how to use the gmp Ruby gem, which provides bindings to
42
42
  the GNU multiple precision arithmetic library, version 4.3.x or 5.0.x.\\
43
43
  \\
44
- Copyright 2009 Sam Rawlins.\\
44
+ Copyright 2009, 2010 Sam Rawlins.\\
45
45
  No license yet.
46
46
  \newpage
47
47
 
@@ -201,7 +201,29 @@ The gmp gem includes the namespace \texttt{GMP} and four classes within \texttt{
201
201
 
202
202
  In addition to the above four classes, there is also one constant within \texttt{GMP}:
203
203
  \begin{itemize}
204
- \item \texttt{GMP::GMP\_VERSION} - The version of GMP compiled into the gmp gem.
204
+ \item \texttt{GMP::GMP\_VERSION} - The version of GMP linked into the gmp gem
205
+ \item \texttt{GMP::GMP\_CC} - The compiler that compiled GMP linked into the gmp gem
206
+ \item \texttt{GMP::GMP\_CFLAGS} - The compiler flags used to compile GMP linked into
207
+ the gmp gem
208
+ \item \texttt{GMP::GMP\_BITS\_PER\_LIMB} - The number of bits per limb
209
+ \end{itemize}
210
+
211
+ \section{MPFR basics}
212
+
213
+ The gmp gem can optionally link to MPFR, the Multiple Precision Floating-Point Reliable
214
+ Library. The x86-mswin32 version of the gmp gem comes with MPFR. This library uses the
215
+ floating-point type from GMP, and thus the MPFR functions mapped in the gmp gem become
216
+ methods in \texttt{GMP::F}.
217
+
218
+ There are additional constants within \texttt{GMP} when MPFR is linked:
219
+ \begin{itemize}
220
+ \item \texttt{GMP::MPFR\_VERSION} - The version of MPFR linked into the gmp gem.
221
+ \item \texttt{GMP::GMP\_RNDN} - Rounding mode representing "round to nearest."
222
+ \item \texttt{GMP::GMP\_RNDZ} - Rounding mode representing "round toward zero."
223
+ \item \texttt{GMP::GMP\_RNDU} - Rounding mode representing "round toward positive
224
+ infinity."
225
+ \item \texttt{GMP::GMP\_RNDD} - Rounding mode representing "round toward negative
226
+ infinity."
205
227
  \end{itemize}
206
228
 
207
229
  \newpage
@@ -693,8 +715,6 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
693
715
  }
694
716
  \end{tabular}
695
717
 
696
-
697
-
698
718
  \subsection{Integer Logic and Bit Fiddling}
699
719
 
700
720
  \begin{tabular}{p{\methwidth} l r}
@@ -742,6 +762,35 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
742
762
  }
743
763
  \end{tabular}
744
764
 
765
+ \newpage
766
+ \section{Rational Functions}
767
+
768
+ \subsection{Initializing, Assigning Rationals}
769
+
770
+ \begin{tabular}{p{\methwidth} l r}
771
+ \toprule
772
+ \textbf{new} & & GMP::Q.new $\rightarrow$ \textit{rational} \\
773
+ & & GMP::Q.new(\textit{numerator = 0}, \textit{denominator = 1}) $\rightarrow$ \textit{rational} \\
774
+ & & GMP::Q.new(\textit{str}) $\rightarrow$ \textit{rational} \\
775
+ \cmidrule(r){2-3}
776
+ & \multicolumn{2}{p{\defnwidth}}{
777
+ This method creates a new \textit{GMP::Q} rational number. It takes two optional
778
+ arguments for the value of the numerator and denominator. These arguments can each be
779
+ an instance of several classes. Here are some
780
+ examples:\newline
781
+
782
+ \texttt{GMP::Q.new \qqqquad\qqqquad \#=> 0 (default) \newline
783
+ GMP::Q.new(1) \qqqquad\qquad\ \#=> 1 (Ruby Fixnum) \newline
784
+ GMP::Q.new(1,3) \qqqquad\ \#=> 1/3 (Ruby Fixnums) \newline
785
+ GMP::Q.new("127") \qqqquad\ \#=> 127 (Ruby String)\newline
786
+ GMP::Q.new(4294967296) \qquad \#=> 4294967296 (Ruby Bignum)\newline
787
+ GMP::Q.new(GMP::Z.new(31)) \#=> 31 (GMP Integer)}
788
+ }
789
+ \end{tabular}
790
+ \newline\newline
791
+
792
+ There is also a convenience method available, \texttt{GMP::Q()}.\\
793
+
745
794
  \newpage
746
795
  \section{Random Number Functions}
747
796
 
@@ -793,12 +842,23 @@ There is also a convenience method available, \texttt{GMP::Z()}.\\
793
842
 
794
843
  \begin{tabular}{p{\methwidth} l r}
795
844
  \toprule
796
- \textbf{urandomb} & & $state$.urandomb($n$) $\rightarrow$ $n$ \\
845
+ \textbf{urandomb} & & $state$.urandomb($n$) $\rightarrow$ $integer$ \\
797
846
  \cmidrule(r){2-3}
798
847
  & \multicolumn{2}{p{\defnwidth}}{
799
848
  Generates a uniformly distributed random integer in the range $0$ to $2^n -1$,
800
849
  inclusive.
801
850
  }
802
851
  \end{tabular}
852
+ \newline\newline
853
+
854
+ \begin{tabular}{p{\methwidth} l r}
855
+ \toprule
856
+ \textbf{urandomm} & & $state$.urandomm($n$) $\rightarrow$ $integer$ \\
857
+ \cmidrule(r){2-3}
858
+ & \multicolumn{2}{p{\defnwidth}}{
859
+ Generates a uniformly distributed random integer in the range $0$ to $n -1$,
860
+ inclusive. $n$ can be an instance of \gmpz, $Fixnum$, or $Bignum$.
861
+ }
862
+ \end{tabular}
803
863
 
804
864
  \end{document}
@@ -0,0 +1,53 @@
1
+ require 'test_helper'
2
+
3
+ class MPFR_TSQRT < Test::Unit::TestCase
4
+ def setup
5
+ @rand_state = GMP::RandState.new
6
+ end
7
+
8
+ # This really should be moved to be a method of GMP::F
9
+ def integer_component(f)
10
+ index_e = f.to_s.index('e')
11
+ exp = f.to_s[(index_e+1)..-1].to_i
12
+ return 0 if exp < 0
13
+ f.to_s[2..(index_e-1)][0,exp]
14
+ end
15
+
16
+ def check_diverse(as, p, qs)
17
+ q = GMP::F(as, p)
18
+ q = q.sqrt
19
+ assert_equal(integer_component(q), qs)
20
+ end
21
+
22
+ def property1(p, rounding)
23
+ current_rounding_mode = GMP::F.default_rounding_mode
24
+ GMP::F.default_rounding_mode = rounding
25
+ x = @rand_state.mpfr_urandomb(p)
26
+ y = @rand_state.mpfr_urandomb(p)
27
+ z = x**2 + y**2
28
+ z = x / z.sqrt
29
+ assert_between(-1, 1, z, "-1 <= x/sqrt(x^2+y^2) <= 1 should hold.")
30
+ GMP::F.default_rounding_mode = GMP.const_get(current_rounding_mode)
31
+ end
32
+
33
+ def property2(p, rounding)
34
+ current_rounding_mode = GMP::F.default_rounding_mode
35
+ GMP::F.default_rounding_mode = rounding
36
+ x = @rand_state.mpfr_urandomb(p)
37
+ y = (x ** 2).sqrt
38
+ assert_true(x == y, "sqrt(x^2) = x should hold.")
39
+ GMP::F.default_rounding_mode = GMP.const_get(current_rounding_mode)
40
+ end
41
+
42
+ def test_prec
43
+ (GMP::MPFR_PREC_MIN..128).each do |p|
44
+ property1(p, GMP::GMP_RNDN)
45
+ property1(p, GMP::GMP_RNDU)
46
+ property2(p, GMP::GMP_RNDN)
47
+ end
48
+
49
+ check_diverse("635030154261163106768013773815762607450069292760790610550915652722277604820131530404842415587328",
50
+ 160,
51
+ "796887792767063979679855997149887366668464780637")
52
+ end
53
+ end
@@ -2,47 +2,112 @@ require 'test_helper'
2
2
 
3
3
  class TC_precision < Test::Unit::TestCase
4
4
  def setup
5
+ begin
6
+ GMP::MPFR_VERSION
7
+ @initial_default_prec = GMP::F.default_prec
8
+ rescue
9
+ @initial_default_prec = GMP::F.default_prec
10
+ end
11
+ end
12
+
13
+ def test_initial_default_precision
14
+ begin
15
+ GMP::MPFR_VERSION
16
+ assert_equal(53, GMP::F.default_prec, "The initial default precision with MPFR should be 53.")
17
+ rescue
18
+ assert_equal(64, GMP::F.default_prec, "The initial default precision without MPFR should be 64.")
19
+ end
20
+ end
21
+
22
+ def test_initial_default_precision2
5
23
  @pi = GMP::F.new(3.14)
6
24
  @seven_halves = GMP::F.new(GMP::Q.new(7,2), 1000)
25
+ assert_in_delta(0, GMP::F.new(), 1e-12)
26
+ assert_equal(@initial_default_prec, GMP::F.new().prec)
27
+ assert_in_delta(3.14000000000000012434, @pi, 1e-12)
28
+ assert_equal(@initial_default_prec, @pi.prec)
29
+ assert_in_delta(1, GMP::F.new(1), 1e-12)
30
+ assert_equal(@initial_default_prec, GMP::F.new(1).prec)
31
+ assert_in_delta(3.14, GMP::F.new("3.14"), 1e-12)
32
+ assert_equal(@initial_default_prec, GMP::F.new("3.14").prec)
33
+ assert_in_delta(4294967296, GMP::F.new(2**32), 1e-12)
34
+ assert_equal(@initial_default_prec, GMP::F.new(2**32).prec)
35
+ assert_in_delta(3, GMP::F.new(GMP::Z.new(3)), 1e-12)
36
+ assert_equal(@initial_default_prec, GMP::F.new(GMP::Z.new(3)).prec)
37
+ assert_in_delta(3.5, GMP::F.new(GMP::Q.new(7,2)), 1e-12)
38
+ assert_equal(@initial_default_prec, GMP::F.new(GMP::Q.new(7,2)).prec)
39
+ assert_in_delta(3.14000000000000012434, GMP::F.new(@pi), 1e-12)
40
+ assert_equal(@initial_default_prec, GMP::F.new(@pi).prec)
7
41
  end
8
42
 
9
43
  def test_default_precision
10
- assert_equal("0.e+0", GMP::F.new().to_s)
11
- assert_equal(64, GMP::F.new().prec)
12
- assert_equal("0.314000000000000012434e+1", @pi.to_s)
13
- assert_equal(64, @pi.prec)
14
- assert_equal("0.1e+1", GMP::F.new(1).to_s)
15
- assert_equal(64, GMP::F.new(1).prec)
16
- assert_equal("0.314e+1", GMP::F.new("3.14").to_s)
17
- assert_equal(64, GMP::F.new("3.14").prec)
18
- assert_equal("0.4294967296e+10", GMP::F.new(2**32).to_s)
19
- assert_equal(64, GMP::F.new(2**32).prec)
20
- assert_equal("0.3e+1", GMP::F.new(GMP::Z.new(3)).to_s)
21
- assert_equal(64, GMP::F.new(GMP::Z.new(3)).prec)
22
- assert_equal("0.35e+1", GMP::F.new(GMP::Q.new(7,2)).to_s)
23
- assert_equal(64, GMP::F.new(GMP::Q.new(7,2)).prec)
24
- assert_equal("0.314000000000000012434e+1", GMP::F.new(@pi).to_s)
25
- assert_equal(64, GMP::F.new(@pi).prec)
44
+ GMP::F.default_prec = 128
45
+ @pi = GMP::F.new(3.14)
46
+ @seven_halves = GMP::F.new(GMP::Q.new(7,2), 1000)
47
+ assert_in_delta(0, GMP::F.new(), 1e-12)
48
+ assert_equal(128, GMP::F.new().prec)
49
+ assert_in_delta(3.14000000000000012434, @pi, 1e-12)
50
+ assert_equal(128, @pi.prec)
51
+ assert_in_delta(1, GMP::F.new(1), 1e-12)
52
+ assert_equal(128, GMP::F.new(1).prec)
53
+ assert_in_delta(3.14, GMP::F.new("3.14"), 1e-12)
54
+ assert_equal(128, GMP::F.new("3.14").prec)
55
+ assert_in_delta(4294967296, GMP::F.new(2**32), 1e-12)
56
+ assert_equal(128, GMP::F.new(2**32).prec)
57
+ assert_in_delta(3, GMP::F.new(GMP::Z.new(3)), 1e-12)
58
+ assert_equal(128, GMP::F.new(GMP::Z.new(3)).prec)
59
+ assert_in_delta(3.5, GMP::F.new(GMP::Q.new(7,2)), 1e-12)
60
+ assert_equal(128, GMP::F.new(GMP::Q.new(7,2)).prec)
61
+ assert_in_delta(3.14000000000000012434, GMP::F.new(@pi), 1e-12)
62
+ assert_equal(128, GMP::F.new(@pi).prec)
63
+ GMP::F.default_prec = @initial_default_prec
26
64
  end
27
65
 
28
66
  def test_specific_precision
29
- assert_equal("0.3140000000000000124344978758017532527446746826171875e+1", GMP::F.new(3.14, 1000).to_s)
30
- assert_equal(1024, GMP::F.new(3.14, 1000).prec)
31
- assert_equal("0.1e+1", GMP::F.new(1, 1000).to_s)
32
- assert_equal(1024, GMP::F.new(1, 1000).prec)
33
- assert_equal("0.314e+1", GMP::F.new("3.14", 1000).to_s)
34
- assert_equal(1024, GMP::F.new("3.14", 1000).prec)
35
- assert_equal("0.4294967296e+10", GMP::F.new(2**32, 1000).to_s)
36
- assert_equal(1024, GMP::F.new(2**32, 1000).prec)
37
- assert_equal("0.3e+1", GMP::F.new(GMP::Z.new(3), 1000).to_s)
38
- assert_equal(1024, GMP::F.new(GMP::Z.new(3), 1000).prec)
39
- assert_equal("0.35e+1", @seven_halves.to_s)
40
- assert_equal(1024, @seven_halves.prec)
41
- assert_equal("0.35e+1", GMP::F.new(@seven_halves).to_s)
42
- assert_equal(1024, GMP::F.new(@seven_halves).prec)
43
- assert_equal("0.3140000000000000124344978758017532527446746826171875e+1", GMP::F.new(@pi, 1000).to_s)
44
- assert_equal(1024, GMP::F.new(@pi, 1000).prec)
45
- assert_equal("0.35e+1", GMP::F.new(@seven_halves, 0).to_s)
46
- assert_equal(64, GMP::F.new(@seven_halves, 0).prec)
67
+ @pi = GMP::F.new(3.14)
68
+ @seven_halves = GMP::F.new(GMP::Q.new(7,2), 1024)
69
+ assert_equal(0, GMP::F.new(3.14, 1024).to_s =~ /0\.31400000000000001243449787580175325274467468261718750*e\+1/)
70
+ assert_equal(1024, GMP::F.new(3.14, 1024).prec)
71
+ assert_in_delta(1, GMP::F.new(1, 1024), 1e-12)
72
+ assert_equal(1024, GMP::F.new(1, 1024).prec)
73
+ assert_in_delta(3.14, GMP::F.new("3.14", 1024), 1e-12)
74
+ assert_equal(1024, GMP::F.new("3.14", 1024).prec)
75
+ assert_in_delta(4294967296, GMP::F.new(2**32, 1024), 1e-12)
76
+ assert_equal(1024, GMP::F.new(2**32, 1024).prec)
77
+ assert_in_delta(3, GMP::F.new(GMP::Z.new(3), 1024), 1e-12)
78
+ assert_equal(1024, GMP::F.new(GMP::Z.new(3), 1024).prec)
79
+ assert_in_delta(3.5, @seven_halves, 1e-12)
80
+ assert_equal(1024, @seven_halves.prec)
81
+ assert_in_delta(3.5, GMP::F.new(@seven_halves), 1e-12)
82
+ assert_equal(1024, GMP::F.new(@seven_halves).prec)
83
+ assert_equal(0, GMP::F.new(@pi, 1024).to_s =~ /0\.31400000000000001243449787580175325274467468261718750*e\+1/)
84
+ assert_equal(1024, GMP::F.new(@pi, 1024).prec)
85
+ assert_in_delta(3.5, GMP::F.new(@seven_halves, 0), 1e-12)
86
+ assert_equal(@initial_default_prec, GMP::F.new(@seven_halves, 0).prec)
87
+ end
88
+
89
+ def test_set_default_prec
90
+ begin
91
+ GMP::MPFR_VERSION
92
+ GMP::F.default_prec = 100
93
+ assert_equal(100, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
94
+ GMP::F.default_prec = 130
95
+ assert_equal(130, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
96
+ GMP::F.default_prec = 1000
97
+ assert_equal(1000, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
98
+ assert_raise(RangeError) { GMP::F.default_prec = -64 }
99
+ assert_raise(TypeError) { GMP::F.default_prec = "Cow" }
100
+ rescue NameError => err
101
+ raise unless err.to_s == "uninitialized constant GMP::MPFR_VERSION"
102
+ GMP::F.default_prec = 100
103
+ assert_equal(128, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
104
+ GMP::F.default_prec = 130
105
+ assert_equal(160, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
106
+ GMP::F.default_prec = 1000
107
+ assert_equal(1024, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
108
+ assert_raise(RangeError) { GMP::F.default_prec = -64 }
109
+ assert_raise(TypeError) { GMP::F.default_prec = "Cow" }
110
+ end
111
+ GMP::F.default_prec = @initial_default_prec
47
112
  end
48
113
  end
@@ -0,0 +1,45 @@
1
+ require 'test_helper'
2
+
3
+ class TC_MPFR_Functions < Test::Unit::TestCase
4
+ def setup
5
+ @a = GMP::F(1)
6
+ end
7
+
8
+ def test_const_existence
9
+ assert_nothing_raised("GMP::F#const_log2 should be callable.") { GMP::F.const_log2 }
10
+ assert_nothing_raised("GMP::F#const_pi should be callable.") { GMP::F.const_pi }
11
+ assert_nothing_raised("GMP::F#const_euler should be callable.") { GMP::F.const_euler }
12
+ assert_nothing_raised("GMP::F#const_catalan should be callable.") { GMP::F.const_catalan }
13
+ end
14
+
15
+ def test_function_existence
16
+ assert_nothing_raised("GMP::F.sqrt should be callable.") { @a.sqrt }
17
+
18
+ assert_nothing_raised("GMP::F.log should be callable.") { @a.log }
19
+ assert_nothing_raised("GMP::F.log2 should be callable.") { @a.log2 }
20
+ assert_nothing_raised("GMP::F.log10 should be callable.") { @a.log10 }
21
+ assert_nothing_raised("GMP::F.exp should be callable.") { @a.exp }
22
+
23
+ assert_nothing_raised("GMP::F.cos should be callable.") { @a.cos }
24
+ assert_nothing_raised("GMP::F.sin should be callable.") { @a.sin }
25
+ assert_nothing_raised("GMP::F.tan should be callable.") { @a.tan }
26
+ assert_nothing_raised("GMP::F.sec should be callable.") { @a.sec }
27
+ assert_nothing_raised("GMP::F.csc should be callable.") { @a.csc }
28
+ assert_nothing_raised("GMP::F.cot should be callable.") { @a.cot }
29
+
30
+ assert_nothing_raised("GMP::F.acos should be callable.") { @a.acos }
31
+ assert_nothing_raised("GMP::F.asin should be callable.") { @a.asin }
32
+ assert_nothing_raised("GMP::F.atan should be callable.") { @a.atan }
33
+
34
+ assert_nothing_raised("GMP::F.cosh should be callable.") { @a.cosh }
35
+ assert_nothing_raised("GMP::F.sinh should be callable.") { @a.sinh }
36
+ assert_nothing_raised("GMP::F.tanh should be callable.") { @a.tanh }
37
+
38
+ assert_nothing_raised("GMP::F.acosh should be callable.") { @a.acosh }
39
+ assert_nothing_raised("GMP::F.asinh should be callable.") { @a.asinh }
40
+ assert_nothing_raised("GMP::F.atanh should be callable.") { @a.atanh }
41
+
42
+ assert_nothing_raised("GMP::F.log1p should be callable.") { @a.log1p }
43
+ assert_nothing_raised("GMP::F.expm1 should be callable.") { @a.expm1 }
44
+ end
45
+ end
@@ -0,0 +1,49 @@
1
+ require 'test_helper'
2
+
3
+ class TC_MPFR_Random < Test::Unit::TestCase
4
+ def setup
5
+ end
6
+
7
+ def test_urandomb
8
+ @a = GMP::RandState.new
9
+ @a.seed(577)
10
+ g1 = [
11
+ GMP::F("0.39810885576093713"), GMP::F("0.97212443610368071"), GMP::F("0.23084385480845748"),
12
+ GMP::F("0.29428636987062717"), GMP::F("0.76895428585342840"), GMP::F("0.69329332764704654"),
13
+ GMP::F("0.60252711974045448"), GMP::F("0.03530920538566051"), GMP::F("0.60242124958975374"),
14
+ ]
15
+ g1.size.times do |i|
16
+ assert_in_delta(g1[i], @a.mpfr_urandomb, 1e-12, "GMP::RandState should mpfr_urandomb predictably.")
17
+ end
18
+ end
19
+
20
+ def test_reseed
21
+ @c = GMP::RandState.new
22
+ @c.seed(1000)
23
+ assert_in_delta(GMP::F("0.78522728792921048"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
24
+ assert_in_delta(GMP::F("0.94422653925308231"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
25
+ assert_in_delta(GMP::F("0.60678541956109799"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
26
+ @c.seed(1000)
27
+ assert_in_delta(GMP::F("0.78522728792921048"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
28
+ assert_in_delta(GMP::F("0.94422653925308231"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
29
+ assert_in_delta(GMP::F("0.60678541956109799"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
30
+ @c.seed(1000)
31
+ assert_in_delta(GMP::F("0.78522728792921048"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
32
+ assert_in_delta(GMP::F("0.94422653925308231"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
33
+ assert_in_delta(GMP::F("0.60678541956109799"), @c.mpfr_urandomb, 1e-12, "GMP::RandState should re-seed correctly.")
34
+ end
35
+
36
+ def test_random_independent_states
37
+ @d = GMP::RandState.new
38
+ @d.seed(577)
39
+ @e = GMP::RandState.new
40
+ @e.seed(577)
41
+
42
+ assert_in_delta(GMP::F("0.39810885576093713"), @d.mpfr_urandomb, 1e-12, "GMP::RandState should be independent correctly.")
43
+ assert_in_delta(GMP::F("0.97212443610368071"), @d.mpfr_urandomb, 1e-12, "GMP::RandState should be independent correctly.")
44
+ assert_in_delta(GMP::F("0.39810885576093713"), @e.mpfr_urandomb, 1e-12, "GMP::RandState should be independent correctly.")
45
+ assert_in_delta(GMP::F("0.97212443610368071"), @e.mpfr_urandomb, 1e-12, "GMP::RandState should be independent correctly.")
46
+ assert_in_delta(GMP::F("0.23084385480845748"), @d.mpfr_urandomb, 1e-12, "GMP::RandState should be independent correctly.")
47
+ assert_in_delta(GMP::F("0.23084385480845748"), @e.mpfr_urandomb, 1e-12, "GMP::RandState should be independent correctly.")
48
+ end
49
+ end
@@ -1,4 +1,5 @@
1
1
  require 'test/unit'
2
+ require 'test_unit/assertions' # Monkey patch
2
3
  require 'rbconfig'
3
4
 
4
5
  ENV['PATH'] = [File.expand_path(
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'test_helper'
4
+
4
5
  require 'tc_z'
5
6
  require 'tc_z_basic'
6
7
  require 'tc_z_logic'
@@ -23,17 +24,11 @@ require 'tc_z_jac_leg_rem'
23
24
  require 'tc_z_gcd_lcm_invert'
24
25
  require 'tc_random'
25
26
 
26
- class TC_default_prec < Test::Unit::TestCase
27
- def test_default_prec
28
- assert_equal( 64, GMP::F.default_prec, "GMP::F.default_prec should be 64.")
29
- GMP::F.default_prec = 100
30
- assert_equal(128, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
31
- GMP::F.default_prec = 130
32
- assert_equal(160, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
33
- GMP::F.default_prec = 1000
34
- assert_equal(1024, GMP::F.default_prec, "GMP::F.default_prec should be assignable.")
35
- assert_raise(RangeError) { GMP::F.default_prec = -64 }
36
- assert_raise(TypeError) { GMP::F.default_prec = "Cow" }
37
- GMP::F.default_prec = 64
38
- end
39
- end
27
+ begin
28
+ GMP::MPFR_VERSION
29
+ require 'tc_mpfr_random'
30
+ require 'tc_mpfr_functions'
31
+ require 'mpfr_tsqrt'
32
+ rescue
33
+
34
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gmp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomasz Wegrzanowski
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2010-03-01 00:00:00 -07:00
13
+ date: 2010-03-08 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -37,6 +37,7 @@ files:
37
37
  - ext/ruby_gmp.h
38
38
  - ext/takeover.h
39
39
  - ext/extconf.rb
40
+ - test/mpfr_tsqrt.rb
40
41
  - test/tc_cmp.rb
41
42
  - test/tc_division.rb
42
43
  - test/tc_fib_fac_nextprime.rb
@@ -44,6 +45,8 @@ files:
44
45
  - test/tc_f_arithmetics_coersion.rb
45
46
  - test/tc_f_precision.rb
46
47
  - test/tc_logical_roots.rb
48
+ - test/tc_mpfr_functions.rb
49
+ - test/tc_mpfr_random.rb
47
50
  - test/tc_q.rb
48
51
  - test/tc_q_basic.rb
49
52
  - test/tc_random.rb
@@ -90,7 +93,7 @@ post_install_message:
90
93
  rdoc_options: []
91
94
 
92
95
  require_paths:
93
- - ext
96
+ - lib
94
97
  required_ruby_version: !ruby/object:Gem::Requirement
95
98
  requirements:
96
99
  - - ">="