number 0.9.3 → 0.9.4

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.
Files changed (3) hide show
  1. data/ext/number.c +79 -0
  2. data/ext/real.c +5 -0
  3. metadata +2 -2
@@ -3,6 +3,84 @@
3
3
  long digs;
4
4
  VALUE rb_cNumber;
5
5
 
6
+ VALUE rb_String_to_number (VALUE str)
7
+ {
8
+ VALUE complex_regex = rb_enc_reg_new("^(.*[^\\s]+)\\s*\\+\\s*(.*)i$", strlen("^(.*[^\\s]+)\\s*\\+\\s*(.*)i$"), rb_utf8_encoding(), 0);
9
+ VALUE complex_match = rb_funcall(complex_regex, rb_intern("match"), 1, str);
10
+
11
+ if (RTEST(complex_match))
12
+ {
13
+ VALUE complex_captures = rb_funcall(complex_match, rb_intern("captures"), 0);
14
+ return rb_funcall(Qnil, rb_intern("Number"), 2, RARRAY_PTR(complex_captures)[0], RARRAY_PTR(complex_captures)[1]);
15
+ }
16
+ else
17
+ {
18
+ VALUE interval_regex = rb_enc_reg_new("^\\[(.*[^\\s]+)\\s*([<≤])\\s*\\((.*[^\\s]+)\\)\\s*([<≤])\\s*(.*[^\\s]+)\\]$", strlen("^\\[(.*[^\\s]+)\\s*([<≤])\\s*\\((.*[^\\s]+)\\)\\s*([<≤])\\s*(.*[^\\s]+)\\]$"), rb_utf8_encoding(), 0);
19
+ VALUE interval_match = rb_funcall(interval_regex, rb_intern("match"), 1, str);
20
+
21
+ if (RTEST(interval_match))
22
+ {
23
+ VALUE interval_captures = rb_funcall(interval_match, rb_intern("captures"), 0);
24
+ return rb_funcall(Qnil, rb_intern("Number"), 5, RARRAY_PTR(interval_captures)[0], RARRAY_PTR(interval_captures)[2], RARRAY_PTR(interval_captures)[4], *RSTRING_PTR(RARRAY_PTR(interval_captures)[2]) == '<' ? Qtrue : Qfalse, *RSTRING_PTR(RARRAY_PTR(interval_captures)[4]) == '<' ? Qtrue : Qfalse);
25
+ }
26
+ else
27
+ {
28
+ VALUE real_regex = rb_enc_reg_new("^([+-]?[0-9]+):([+-]?[0-9]+)$", strlen("^([+-]?[0-9]+):([+-]?[0-9]+)$"), rb_utf8_encoding(), 0);
29
+ VALUE real_match = rb_funcall(real_regex, rb_intern("match"), 1, str);
30
+
31
+ if (RTEST(real_match))
32
+ {
33
+ VALUE real_captures = rb_funcall(real_match, rb_intern("captures"), 0);
34
+ VALUE result = rb_obj_alloc(rb_cNumber);
35
+ Real* real = (Real*)real_from_str(RSTRING_PTR(RARRAY_PTR(real_captures)[0]), NUM2LONG(rb_funcall(RARRAY_PTR(real_captures)[1], rb_intern("to_i"), 0)));
36
+
37
+ DATA_PTR(result) = (Complex*)complex_from_real(real);
38
+ real_free(real);
39
+
40
+ return result;
41
+ }
42
+ else if ((long)RSTRING_PTR(str)[0] == -61)
43
+ {
44
+ VALUE result = rb_obj_alloc(rb_cNumber);
45
+ DATA_PTR(result) = (Complex*)complex_nan();
46
+
47
+ return result;
48
+ }
49
+ else if ((long)RSTRING_PTR(str)[0] == -30)
50
+ {
51
+ VALUE result = rb_obj_alloc(rb_cNumber);
52
+ DATA_PTR(result) = (Complex*)complex_pos_inf();
53
+
54
+ return result;
55
+ }
56
+ else if (((long)RSTRING_PTR(str)[0] == 43 || (long)RSTRING_PTR(str)[0] == 45) && (long)RSTRING_PTR(str)[1] == -30)
57
+ {
58
+ VALUE result = rb_obj_alloc(rb_cNumber);
59
+ DATA_PTR(result) = ((long)RSTRING_PTR(str)[0] == 43) ? (Complex*)complex_pos_inf() : (Complex*)complex_neg_inf();
60
+
61
+ return result;
62
+ }
63
+ else
64
+ {
65
+ VALUE integer_regex = rb_enc_reg_new("^([+-]?[0-9]+)$", strlen("^([+-]?[0-9]+)$"), rb_utf8_encoding(), 0);
66
+ VALUE integer_match = rb_funcall(integer_regex, rb_intern("match"), 1, str);
67
+
68
+ if (RTEST(integer_match))
69
+ {
70
+ return rb_funcall(rb_funcall(str, rb_intern("to_i"), 0), rb_intern("to_number"), 0);
71
+ }
72
+ else
73
+ {
74
+ return rb_funcall(rb_funcall(str, rb_intern("to_f"), 0), rb_intern("to_number"), 0);
75
+ }
76
+ }
77
+ }
78
+ }
79
+
80
+ /* not reached */
81
+ return Qnil;
82
+ }
83
+
6
84
  VALUE rb_Integer_to_number (VALUE integer)
7
85
  {
8
86
  VALUE result = rb_obj_alloc(rb_cNumber);
@@ -1277,6 +1355,7 @@ void Init_number ()
1277
1355
 
1278
1356
  digs = 17;
1279
1357
 
1358
+ rb_define_method(rb_cString, "to_number", rb_String_to_number, 0);
1280
1359
  rb_define_method(rb_cInteger, "to_number", rb_Integer_to_number, 0);
1281
1360
  rb_define_method(rb_cFloat, "to_number", rb_Float_to_number, 0);
1282
1361
  rb_define_method(rb_cComplex, "to_number", rb_Complex_to_number, 0);
data/ext/real.c CHANGED
@@ -797,6 +797,11 @@ Real* real_divide (Real* a, Real* b, int round_mode)
797
797
  mpfr_t b_num;
798
798
  mpfr_t num;
799
799
 
800
+ if (!REAL(a) || !REAL(b))
801
+ {
802
+ return (NaN(a) || NaN(b) || (!REAL(a) && !REAL(b))) ? real_nan() : !REAL(b) ? real_zero() : (POS(a) && POS(b)) ? real_pos_inf() : real_neg_inf();
803
+ }
804
+
800
805
  mpfr_init2(num, PREC);
801
806
  mpfr_init_set_r(a_num, a);
802
807
  mpfr_init_set_r(b_num, b);
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: number
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.9.3
5
+ version: 0.9.4
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jesse Sielaff
@@ -12,7 +12,7 @@ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
14
 
15
- date: 2011-07-15 00:00:00 Z
15
+ date: 2011-07-16 00:00:00 Z
16
16
  dependencies: []
17
17
 
18
18
  description: The Number gem is intended to be a drop-in replacement for Ruby's Numeric classes when arbitrary-precision complex interval calculations are warranted. The basis of the arbitrary-precision calculations is the GNU MP, MPFR, and MPC libraries.