number 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
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.