fibonacci 0.1.5 → 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,73 +11,161 @@
11
11
  #define ONE INT2NUM(1)
12
12
  #define ZERO INT2NUM(0)
13
13
  #define TWO INT2NUM(2)
14
+ #define THREE INT2NUM(3)
15
+ #define MINUS_ONE INT2NUM(-1)
14
16
  #define ARY_LEN 2L
15
17
 
16
18
  static VALUE cFibonacci;
17
- static ID id_plus;
18
- static ID id_lte;
19
- static ID id_gte;
20
- static ID id_lt;
21
- static ID id_pow;
22
- static ID id_minus;
23
- static ID id_fdiv;
24
- static ID id_div;
25
- static ID id_to_i;
26
- static ID id_log10;
27
- static ID id_floor;
28
- static ID id_sqrt;
29
- static ID id_mul;
30
- static ID id_eq;
31
- static ID id_not_eq;
32
- static ID id_mod;
19
+ static ID id_plus, id_lte, id_gte, id_lt, id_pow, id_minus, id_fdiv, id_div;
20
+ static ID id_to_i, id_log10, id_floor, id_sqrt, id_mul, id_eq, id_not_eq;
21
+ static ID id_mod, id_bit_and, id_log2;
33
22
 
34
23
  static VALUE
35
24
  fibonacci_init(VALUE self)
36
25
  {
37
- return self;
26
+ return self;
38
27
  }
39
28
 
40
29
  static VALUE
41
30
  rb_print_num(VALUE num)
42
31
  {
43
- VALUE num_str = rb_funcall(num, rb_intern("to_s"), 0);
44
- char *cptr = StringValuePtr(num_str);
45
- printf("%s\n", cptr);
46
- return Qnil;
32
+ VALUE num_str = rb_funcall(num, rb_intern("to_s"), 0);
33
+ char *cptr = StringValuePtr(num_str);
34
+ printf("%s\n", cptr);
35
+ return Qnil;
47
36
  }
48
37
 
38
+
39
+ /* call-seq:
40
+ * fib.fast_val(n)
41
+ *
42
+ * Returns a Fixnum or Bignum.
43
+ *
44
+ * fib.fast_val(100)
45
+ * #=> 354224848179261915075
46
+ *
47
+ * fib.fast_val(10)
48
+ * #=> 55
49
+ *
50
+ * fib.fast_val(200)
51
+ * #=> 280571172992510140037611932413038677189525
52
+ *
53
+ *
54
+ * ref: Daisuke Takahashi, A fast algorithm for computing large Fibonacci
55
+ * numbers, Information Processing Letters, Volume 75, Issue 6, 30 November
56
+ * 2000, Pages 243-246, ISSN 0020-0190, 10.1016/S0020-0190(00)00112-5.
57
+ */
58
+
49
59
  static VALUE
50
- rb_matrix_mul(VALUE ary1, VALUE ary2)
60
+ rb_fast_val(VALUE self, VALUE n)
51
61
  {
52
- long i, j, k;
53
- VALUE temp;
54
- VALUE tmp_ary = rb_ary_new2(ARY_LEN);
55
- VALUE zero_ary = rb_ary_new2(ARY_LEN);
56
-
57
- rb_ary_push(zero_ary, ZERO);
58
- rb_ary_push(zero_ary, ZERO);
59
- rb_ary_push(tmp_ary, zero_ary);
60
-
61
- zero_ary = rb_ary_new2(ARY_LEN);
62
- rb_ary_push(zero_ary, ZERO);
63
- rb_ary_push(zero_ary, ZERO);
64
- rb_ary_push(tmp_ary, zero_ary);
65
-
66
- for(i = 0; i < 2; i++)
67
- {
68
- for(j = 0; j < 2; j++)
62
+ VALUE f, l, sign, mask, log2, i, logn, logn_min_1, temp;
63
+
64
+ if(TYPE(n) != T_FIXNUM)
65
+ {
66
+ rb_raise(rb_eArgError, "Invalid argument for type Fixnum");
67
+ return Qnil;
68
+ }
69
+
70
+ if(RTEST(rb_funcall(n, id_lt, 1, ZERO)))
71
+ {
72
+ rb_raise(rb_eArgError, "n cannot be negative");
73
+ return Qnil;
74
+ }
75
+ else
69
76
  {
70
- for(k = 0; k < 2; k++)
77
+ if(rb_equal(n, ZERO))
78
+ {
79
+ return ZERO;
80
+ }
81
+ else if(rb_equal(n, ONE))
82
+ {
83
+ return ONE;
84
+ }
85
+ else if(rb_equal(n, TWO))
71
86
  {
72
- //tmp[i][j] = (tmp[i][j] + ary1[i][k] * ary2[k][j]);
73
- temp = rb_funcall(rb_ary_entry(rb_ary_entry(ary1, i), k), id_mul,
74
- 1, rb_ary_entry(rb_ary_entry(ary2, k), j));
75
- rb_ary_store(rb_ary_entry(tmp_ary, i), j, rb_funcall(temp, id_plus, 1, rb_ary_entry(rb_ary_entry(tmp_ary, i), j)));
87
+ return ONE;
76
88
  }
89
+ else
90
+ {
91
+ f = ONE;
92
+ l = ONE;
93
+ sign = MINUS_ONE;
94
+ logn = rb_funcall(rb_mMath, id_log2, 1, n);
95
+ logn = rb_funcall(logn, id_floor, 0);
96
+ logn_min_1 = rb_funcall(logn, id_minus, 1, ONE);
97
+ mask = rb_funcall(TWO, id_pow, 1, logn_min_1);
98
+ for(i = ONE; RTEST(rb_funcall(i, id_lte, 1, logn_min_1)); i = rb_funcall(i, id_plus, 1, ONE))
99
+ {
100
+ temp = rb_funcall(f, id_mul, 1, f);
101
+ f = rb_funcall(f, id_plus, 1, l);
102
+ f = rb_funcall(f, id_div, 1, TWO);
103
+ f = rb_funcall(rb_funcall(f, id_mul, 1, f), id_mul, 1, TWO);
104
+ f = rb_funcall(f, id_minus, 1, rb_funcall(temp, id_mul, 1, THREE));
105
+ f = rb_funcall(f, id_minus, 1, rb_funcall(sign, id_mul, 1, TWO));
106
+ l = rb_funcall(temp, id_mul, 1, INT2NUM(5));
107
+ l = rb_funcall(l, id_plus, 1, rb_funcall(TWO, id_mul, 1, sign));
108
+ sign = ONE;
109
+ if(!rb_equal(rb_funcall(n, id_bit_and, 1, mask), ZERO))
110
+ {
111
+ temp = f;
112
+ f = rb_funcall(f, id_plus, 1, l);
113
+ f = rb_funcall(f, id_div, 1, TWO);
114
+ l = rb_funcall(TWO, id_mul, 1, temp);
115
+ l = rb_funcall(l, id_plus, 1, f);
116
+ sign = MINUS_ONE;
117
+ }
118
+ mask = rb_funcall(mask, id_div, 1, TWO);
119
+ }
120
+ if(rb_equal(rb_funcall(n, id_bit_and, 1, mask), ZERO))
121
+ {
122
+ f = rb_funcall(f, id_mul, 1, l);
123
+ }
124
+ else
125
+ {
126
+ f = rb_funcall(f, id_plus, 1, l);
127
+ f = rb_funcall(f, id_div, 1, TWO);
128
+ f = rb_funcall(f, id_mul, 1, l);
129
+ f = rb_funcall(f, id_minus, 1, sign);
130
+ }
131
+ }
132
+ }
133
+
134
+ return f;
135
+ }
136
+
137
+ static VALUE
138
+ rb_matrix_mul(VALUE ary1, VALUE ary2)
139
+ {
140
+ long i, j, k;
141
+ VALUE temp;
142
+ VALUE tmp_ary = rb_ary_new2(ARY_LEN);
143
+ VALUE zero_ary = rb_ary_new2(ARY_LEN);
144
+
145
+ rb_ary_push(zero_ary, ZERO);
146
+ rb_ary_push(zero_ary, ZERO);
147
+ rb_ary_push(tmp_ary, zero_ary);
148
+
149
+ zero_ary = rb_ary_new2(ARY_LEN);
150
+ rb_ary_push(zero_ary, ZERO);
151
+ rb_ary_push(zero_ary, ZERO);
152
+ rb_ary_push(tmp_ary, zero_ary);
153
+
154
+ for(i = 0; i < 2; i++)
155
+ {
156
+ for(j = 0; j < 2; j++)
157
+ {
158
+ for(k = 0; k < 2; k++)
159
+ {
160
+ /* tmp[i][j] = (tmp[i][j] + ary1[i][k] * ary2[k][j]); */
161
+ temp = rb_funcall(rb_ary_entry(rb_ary_entry(ary1, i), k), id_mul,
162
+ 1, rb_ary_entry(rb_ary_entry(ary2, k), j));
163
+ rb_ary_store(rb_ary_entry(tmp_ary, i), j, rb_funcall(temp, id_plus, 1, rb_ary_entry(rb_ary_entry(tmp_ary, i), j)));
164
+ }
165
+ }
77
166
  }
78
- }
79
167
 
80
- return tmp_ary;
168
+ return tmp_ary;
81
169
  }
82
170
 
83
171
  /* call-seq:
@@ -85,83 +173,82 @@ rb_matrix_mul(VALUE ary1, VALUE ary2)
85
173
  *
86
174
  * Returns a 2x2 matrix(2-dimensional array).
87
175
  *
88
- * fib.matrix(10)
89
- * #=> [[89, 55], [55, 34]]
176
+ * fib.matrix(10)
177
+ * #=> [[89, 55], [55, 34]]
90
178
  *
91
- * fib.matrix(100)
92
- * #=> [[573147844013817084101, 354224848179261915075], [354224848179261915075,218922995834555169026]]
179
+ * fib.matrix(100)
180
+ * #=> [[573147844013817084101, 354224848179261915075], [354224848179261915075,218922995834555169026]]
93
181
  *
94
- * arr = fib.matrix(15)
95
- * #=> [[987, 610], [610, 377]]
182
+ * arr = fib.matrix(15)
183
+ * #=> [[987, 610], [610, 377]]
96
184
  *
97
- * arr[0][1] or arr[1][0] is the value of nth term
185
+ * arr[0][1] or arr[1][0] is the value of nth term
98
186
  *
99
187
  * Refer to http://en.wikipedia.org/wiki/Fibonacci_number#Matrix_form
100
- *
101
188
  */
102
189
 
103
190
  static VALUE
104
191
  rb_matrix_form(VALUE self, VALUE n)
105
192
  {
106
- VALUE base_ary;
107
- VALUE res_ary;
108
- VALUE tmp_ary;
109
- long ary_len = 2;
110
-
111
- if(TYPE(n) != T_FIXNUM)
112
- {
113
- rb_raise(rb_eArgError, "Invalid argument for type Fixnum");
114
- return Qnil;
115
- }
193
+ VALUE base_ary;
194
+ VALUE res_ary;
195
+ VALUE tmp_ary;
196
+ long ary_len = 2;
116
197
 
117
- if(RTEST(rb_funcall(n, id_lt, 1, ZERO)))
118
- {
119
- rb_raise(rb_eArgError, "n cannot be negative");
120
- return Qnil;
121
- }
122
- else
123
- {
124
- base_ary = rb_ary_new2(ARY_LEN);
125
- res_ary = rb_ary_new2(ARY_LEN);
126
- tmp_ary = rb_ary_new2(ARY_LEN);
127
-
128
- // base is {{1, 1}, {1, 0}}
129
- rb_ary_push(tmp_ary, ONE);
130
- rb_ary_push(tmp_ary, ONE);
131
- rb_ary_push(base_ary, tmp_ary);
132
-
133
- tmp_ary = rb_ary_new2(ARY_LEN);
134
- rb_ary_push(tmp_ary, ONE);
135
- rb_ary_push(tmp_ary, ZERO);
136
- rb_ary_push(base_ary, tmp_ary);
137
-
138
- /*// res is {{1, 0}, {0, 1}}*/
139
- tmp_ary = rb_ary_new2(ARY_LEN);
140
- rb_ary_push(tmp_ary, ONE);
141
- rb_ary_push(tmp_ary, ZERO);
142
- rb_ary_push(res_ary, tmp_ary);
143
-
144
- tmp_ary = rb_ary_new2(ARY_LEN);
145
- rb_ary_push(tmp_ary, ZERO);
146
- rb_ary_push(tmp_ary, ONE);
147
- rb_ary_push(res_ary, tmp_ary);
148
-
149
- while(RTEST(rb_funcall(n, id_not_eq, 1, ZERO)))
198
+ if(TYPE(n) != T_FIXNUM)
150
199
  {
151
- if(RTEST(rb_funcall(rb_funcall(n, id_mod, 1, TWO), id_eq, 1, ZERO)))
152
- {
153
- n = rb_funcall(n, id_div, 1, TWO);
154
- base_ary = rb_matrix_mul(base_ary, base_ary);
155
- }
156
- else
157
- {
158
- n = rb_funcall(n, id_minus, 1, ONE);
159
- res_ary = rb_matrix_mul(res_ary, base_ary);
160
- }
200
+ rb_raise(rb_eArgError, "Invalid argument for type Fixnum");
201
+ return Qnil;
161
202
  }
162
- }
163
203
 
164
- return res_ary;
204
+ if(RTEST(rb_funcall(n, id_lt, 1, ZERO)))
205
+ {
206
+ rb_raise(rb_eArgError, "n cannot be negative");
207
+ return Qnil;
208
+ }
209
+ else
210
+ {
211
+ base_ary = rb_ary_new2(ARY_LEN);
212
+ res_ary = rb_ary_new2(ARY_LEN);
213
+ tmp_ary = rb_ary_new2(ARY_LEN);
214
+
215
+ /* base is {{1, 1}, {1, 0}} */
216
+ rb_ary_push(tmp_ary, ONE);
217
+ rb_ary_push(tmp_ary, ONE);
218
+ rb_ary_push(base_ary, tmp_ary);
219
+
220
+ tmp_ary = rb_ary_new2(ARY_LEN);
221
+ rb_ary_push(tmp_ary, ONE);
222
+ rb_ary_push(tmp_ary, ZERO);
223
+ rb_ary_push(base_ary, tmp_ary);
224
+
225
+ /* res is {{1, 0}, {0, 1}} */
226
+ tmp_ary = rb_ary_new2(ARY_LEN);
227
+ rb_ary_push(tmp_ary, ONE);
228
+ rb_ary_push(tmp_ary, ZERO);
229
+ rb_ary_push(res_ary, tmp_ary);
230
+
231
+ tmp_ary = rb_ary_new2(ARY_LEN);
232
+ rb_ary_push(tmp_ary, ZERO);
233
+ rb_ary_push(tmp_ary, ONE);
234
+ rb_ary_push(res_ary, tmp_ary);
235
+
236
+ while(!rb_equal(n, ZERO))
237
+ {
238
+ if(rb_equal(rb_funcall(n, id_mod, 1, TWO), ZERO))
239
+ {
240
+ n = rb_funcall(n, id_div, 1, TWO);
241
+ base_ary = rb_matrix_mul(base_ary, base_ary);
242
+ }
243
+ else
244
+ {
245
+ n = rb_funcall(n, id_minus, 1, ONE);
246
+ res_ary = rb_matrix_mul(res_ary, base_ary);
247
+ }
248
+ }
249
+ }
250
+
251
+ return res_ary;
165
252
  }
166
253
 
167
254
  /* call-seq:
@@ -169,14 +256,14 @@ rb_matrix_form(VALUE self, VALUE n)
169
256
  *
170
257
  * Returns a Fixnum or Bignum.
171
258
  *
172
- * fib[100]
173
- * #=> 354224848179261915075
259
+ * fib[100]
260
+ * #=> 354224848179261915075
174
261
  *
175
- * fib[10]
176
- * #=> 55
262
+ * fib[10]
263
+ * #=> 55
177
264
  *
178
- * fib[200]
179
- * #=> 280571172992510140037611932413038677189525
265
+ * fib[200]
266
+ * #=> 280571172992510140037611932413038677189525
180
267
  *
181
268
  * The value of nth term is calculated iteratively.
182
269
  *
@@ -186,44 +273,41 @@ rb_matrix_form(VALUE self, VALUE n)
186
273
  static VALUE
187
274
  rb_iterative_val(VALUE self, VALUE n)
188
275
  {
189
- VALUE start = ZERO;
190
- VALUE fib_n_1 = ONE;
191
- VALUE fib_n_2 = ZERO;
192
- VALUE fib_n = ZERO;
193
-
194
- if(TYPE(n) != T_FIXNUM)
195
- {
196
- rb_raise(rb_eArgError, "Invalid argument for type Fixnum");
197
- return Qnil;
198
- }
276
+ VALUE start = TWO;
277
+ VALUE fib_n_1 = ONE;
278
+ VALUE fib_n_2 = ZERO;
279
+ VALUE fib_n = ZERO;
199
280
 
200
- if(RTEST(rb_funcall(n, id_lt, 1, ZERO)))
201
- {
202
- rb_raise(rb_eArgError, "n cannot be negative");
203
- return Qnil;
204
- }
205
- else
206
- {
281
+ if(TYPE(n) != T_FIXNUM)
282
+ {
283
+ rb_raise(rb_eArgError, "Invalid argument for type Fixnum");
284
+ return Qnil;
285
+ }
207
286
 
208
- for(start; RTEST(rb_funcall(start, id_lte, 1, n)); start = rb_funcall(start, id_plus, 1, ONE))
287
+ if(RTEST(rb_funcall(n, id_lt, 1, ZERO)))
209
288
  {
210
- if(RTEST(rb_funcall(start, id_eq, 1, ZERO)))
211
- {
212
- fib_n = ZERO;
213
- }
214
- else if(RTEST(rb_funcall(start, id_eq, 1, ONE)))
215
- {
216
- fib_n = ONE;
217
- }
218
- else
289
+ rb_raise(rb_eArgError, "n cannot be negative");
290
+ return Qnil;
291
+ }
292
+
293
+ if(rb_equal(n, ZERO))
294
+ {
295
+ fib_n = ZERO;
296
+ }
297
+ else if(rb_equal(n, ONE))
298
+ {
299
+ fib_n = ONE;
300
+ }
301
+ else
302
+ {
303
+ for(start; RTEST(rb_funcall(start, id_lte, 1, n)); start = rb_funcall(start, id_plus, 1, ONE))
219
304
  {
220
305
  fib_n = rb_funcall(fib_n_1, id_plus, 1, fib_n_2);
221
306
  fib_n_2 = fib_n_1;
222
307
  fib_n_1 = fib_n;
223
308
  }
224
309
  }
225
- }
226
- return fib_n;
310
+ return fib_n;
227
311
  }
228
312
 
229
313
  /* call-seq:
@@ -231,17 +315,17 @@ rb_iterative_val(VALUE self, VALUE n)
231
315
  *
232
316
  * Returns a array with the first n terms of the series
233
317
  *
234
- * fib.terms(5)
235
- * #=> [0, 1, 1, 2, 3]
318
+ * fib.terms(5)
319
+ * #=> [0, 1, 1, 2, 3]
236
320
  *
237
- * fib.terms(10)
238
- * #=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
321
+ * fib.terms(10)
322
+ * #=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
239
323
  *
240
- * fib.terms(15)
241
- * #=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
324
+ * fib.terms(15)
325
+ * #=> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
242
326
  *
243
- * fib.terms(0)
244
- * #=> []
327
+ * fib.terms(0)
328
+ * #=> []
245
329
  *
246
330
  * Refer to http://en.wikipedia.org/wiki/Fibonacci_number#First_identity
247
331
  */
@@ -249,37 +333,37 @@ rb_iterative_val(VALUE self, VALUE n)
249
333
  static VALUE
250
334
  terms(VALUE self, VALUE n)
251
335
  {
252
- long ary_len = NUM2LONG(n);
253
- long i;
254
- VALUE ary = Qnil;
255
-
256
- if(ary_len < 0)
257
- {
258
- rb_raise(rb_eArgError, "num terms cannot be negative");
259
- return ary;
260
- }
261
-
262
- ary = rb_ary_new2(ary_len);
336
+ long ary_len = NUM2LONG(n);
337
+ long i;
338
+ VALUE ary = Qnil;
263
339
 
264
- for(i=0; i < ary_len; i++)
265
- {
266
- if(i == 0)
340
+ if(ary_len < 0)
267
341
  {
268
- rb_ary_store(ary, i, ZERO);
342
+ rb_raise(rb_eArgError, "num terms cannot be negative");
343
+ return ary;
269
344
  }
270
- if((i > 0))
345
+
346
+ ary = rb_ary_new2(ary_len);
347
+
348
+ for(i=0; i < ary_len; i++)
271
349
  {
272
- if(i <= 2)
273
- {
274
- rb_ary_store(ary, i, ONE);
275
- }
276
- else
277
- {
278
- rb_ary_store(ary, i, rb_funcall(rb_ary_entry(ary, i-1), id_plus, 1, rb_ary_entry(ary, i-2)));
279
- }
350
+ if(i == 0)
351
+ {
352
+ rb_ary_store(ary, i, ZERO);
353
+ }
354
+ if((i > 0))
355
+ {
356
+ if(i <= 2)
357
+ {
358
+ rb_ary_store(ary, i, ONE);
359
+ }
360
+ else
361
+ {
362
+ rb_ary_store(ary, i, rb_funcall(rb_ary_entry(ary, i-1), id_plus, 1, rb_ary_entry(ary, i-2)));
363
+ }
364
+ }
280
365
  }
281
- }
282
- return ary;
366
+ return ary;
283
367
  }
284
368
 
285
369
  /* call-seq:
@@ -287,53 +371,66 @@ terms(VALUE self, VALUE n)
287
371
  *
288
372
  * Prints the first n terms of the series.
289
373
  *
290
- * fib.print(1)
291
- * #=> 0
374
+ * fib.print(1)
375
+ * #=> 0
376
+ *
377
+ * fib.print(2)
378
+ * #=> 0
379
+ * 1
380
+ * fib.print(5)
381
+ * #=> 0
382
+ * 1
383
+ * 1
384
+ * 2
385
+ * 3
292
386
  *
293
- * fib.print(2)
294
- * #=> 0
295
- * 1
296
387
  */
297
388
 
298
389
  static VALUE
299
390
  print(VALUE self, VALUE n)
300
391
  {
301
- VALUE start = ZERO;
302
- VALUE fib_n_1 = ONE;
303
- VALUE fib_n_2 = ZERO;
304
- VALUE fib_n = ZERO;
305
- if(TYPE(n) != T_FIXNUM)
306
- {
307
- rb_raise(rb_eArgError, "Invalid argument for type Fixnum");
308
- return Qnil;
309
- }
392
+ VALUE start = ZERO;
393
+ VALUE fib_n_1 = ONE;
394
+ VALUE fib_n_2 = ZERO;
395
+ VALUE fib_n = ZERO;
310
396
 
311
- for(start; RTEST(rb_funcall(start, id_lt, 1, n)); start = rb_funcall(start, id_plus, 1, ONE))
312
- {
313
- if(RTEST(rb_funcall(start, id_eq, 1, ZERO)))
397
+ if(TYPE(n) != T_FIXNUM)
314
398
  {
315
- rb_print_num(ZERO);
399
+ rb_raise(rb_eArgError, "Invalid argument for type Fixnum");
400
+ return Qnil;
316
401
  }
317
- else if(RTEST(rb_funcall(start, id_eq, 1, ONE)))
402
+
403
+ if(RTEST(rb_funcall(n, id_lt, 1, ZERO)))
318
404
  {
319
- rb_print_num(ONE);
405
+ rb_raise(rb_eArgError, "n cannot be negative");
406
+ return Qnil;
320
407
  }
321
- else
408
+
409
+ for(start; RTEST(rb_funcall(start, id_lt, 1, n)); start = rb_funcall(start, id_plus, 1, ONE))
322
410
  {
323
- fib_n = rb_funcall(fib_n_1, id_plus, 1, fib_n_2);
324
- fib_n_2 = fib_n_1;
325
- fib_n_1 = fib_n;
326
- rb_print_num(fib_n);
411
+ if(rb_equal(start, ZERO))
412
+ {
413
+ rb_print_num(ZERO);
414
+ }
415
+ else if(rb_equal(start, ONE))
416
+ {
417
+ rb_print_num(ONE);
418
+ }
419
+ else
420
+ {
421
+ fib_n = rb_funcall(fib_n_1, id_plus, 1, fib_n_2);
422
+ fib_n_2 = fib_n_1;
423
+ fib_n_1 = fib_n;
424
+ rb_print_num(fib_n);
425
+ }
327
426
  }
328
- }
329
-
330
- return Qnil;
427
+ return Qnil;
331
428
  }
332
429
 
333
430
  static VALUE
334
431
  index_of(VALUE self, VALUE val)
335
432
  {
336
- return Qnil;
433
+ return Qnil;
337
434
  }
338
435
 
339
436
  /* call-seq:
@@ -341,11 +438,11 @@ index_of(VALUE self, VALUE val)
341
438
  *
342
439
  * Returns the number of digits in the nth term of the series
343
440
  *
344
- * fib.num_digits(10)
345
- * #=> 2
441
+ * fib.num_digits(10)
442
+ * #=> 2
346
443
  *
347
- * fib.num_digits(100)
348
- * #=> 21
444
+ * fib.num_digits(100)
445
+ * #=> 21
349
446
  *
350
447
  * Refer to http://en.wikipedia.org/wiki/Fibonacci_number#Computation_by_rounding
351
448
  */
@@ -353,33 +450,31 @@ index_of(VALUE self, VALUE val)
353
450
  static VALUE
354
451
  num_digits(VALUE self, VALUE n)
355
452
  {
356
- if(TYPE(n) != T_FIXNUM)
357
- {
358
- rb_raise(rb_eArgError, "Invalid argument for type Fixnum");
359
- return Qnil;
360
- }
453
+ if(TYPE(n) != T_FIXNUM)
454
+ {
455
+ rb_raise(rb_eArgError, "Invalid argument for type Fixnum");
456
+ return Qnil;
457
+ }
458
+
459
+ if(RTEST(rb_funcall(n, id_lt, 1, ZERO)))
460
+ {
461
+ rb_raise(rb_eArgError, "n cannot be negative");
462
+ return Qnil;
463
+ }
361
464
 
362
- if(RTEST(rb_funcall(n, id_lt, 1, ZERO)))
363
- {
364
- rb_raise(rb_eArgError, "n cannot be negative");
365
- return Qnil;
366
- }
367
- else
368
- {
369
465
  VALUE phi = ONE;
370
466
  VALUE num_digits = ZERO;
371
467
  VALUE log_sqrt_5 = ZERO;
372
468
  VALUE sqrt_5;
373
469
 
374
- if(RTEST(rb_funcall(n, id_eq, 1, ZERO)))
470
+ if(rb_equal(n, ZERO))
375
471
  {
376
472
  return ZERO;
377
473
  }
378
474
 
379
475
  /* work around since the value log(phi/sqrt(5)) + 1 = 0.8595026380819693
380
- * converting to integer would be zero
381
- */
382
- if(RTEST(rb_funcall(n, id_eq, 1, ONE)))
476
+ * converting to integer would be zero */
477
+ if(rb_equal(n, ONE))
383
478
  {
384
479
  return ONE;
385
480
  }
@@ -402,34 +497,36 @@ num_digits(VALUE self, VALUE n)
402
497
 
403
498
  return num_digits;
404
499
  }
405
- }
406
500
  }
407
501
 
408
502
  void
409
503
  Init_fibonacci(void)
410
504
  {
411
- id_plus = rb_intern("+");
412
- id_lte = rb_intern("<=");
413
- id_lt = rb_intern("<");
414
- id_gte = rb_intern(">=");
415
- id_pow = rb_intern("**");
416
- id_mul = rb_intern("*");
417
- id_minus = rb_intern("-");
418
- id_fdiv = rb_intern("fdiv");
419
- id_div = rb_intern("/");
420
- id_to_i = rb_intern("to_i");
421
- id_log10 = rb_intern("log10");
422
- id_floor = rb_intern("floor");
423
- id_sqrt = rb_intern("sqrt");
424
- id_eq = rb_intern("==");
425
- id_not_eq = rb_intern("!=");
426
- id_mod = rb_intern("!=");
427
-
428
- cFibonacci = rb_define_class("Fibonacci", rb_cObject);
429
- rb_define_method(cFibonacci, "initialize", fibonacci_init, 0);
430
- rb_define_method(cFibonacci, "print", print, 1);
431
- rb_define_method(cFibonacci, "terms", terms, 1);
432
- rb_define_method(cFibonacci, "num_digits", num_digits, 1);
433
- rb_define_method(cFibonacci, "[]", rb_iterative_val, 1);
434
- rb_define_method(cFibonacci, "matrix", rb_matrix_form, 1);
505
+ id_plus = rb_intern("+");
506
+ id_lte = rb_intern("<=");
507
+ id_lt = rb_intern("<");
508
+ id_gte = rb_intern(">=");
509
+ id_pow = rb_intern("**");
510
+ id_mul = rb_intern("*");
511
+ id_minus = rb_intern("-");
512
+ id_fdiv = rb_intern("fdiv");
513
+ id_div = rb_intern("/");
514
+ id_to_i = rb_intern("to_i");
515
+ id_log10 = rb_intern("log10");
516
+ id_log2 = rb_intern("log2");
517
+ id_floor = rb_intern("floor");
518
+ id_sqrt = rb_intern("sqrt");
519
+ id_eq = rb_intern("==");
520
+ id_not_eq = rb_intern("!=");
521
+ id_mod = rb_intern("!=");
522
+ id_bit_and = rb_intern("&");
523
+
524
+ cFibonacci = rb_define_class("Fibonacci", rb_cObject);
525
+ rb_define_method(cFibonacci, "initialize", fibonacci_init, 0);
526
+ rb_define_method(cFibonacci, "print", print, 1);
527
+ rb_define_method(cFibonacci, "terms", terms, 1);
528
+ rb_define_method(cFibonacci, "num_digits", num_digits, 1);
529
+ rb_define_method(cFibonacci, "[]", rb_iterative_val, 1);
530
+ rb_define_method(cFibonacci, "matrix", rb_matrix_form, 1);
531
+ rb_define_method(cFibonacci, "fast_val", rb_fast_val, 1);
435
532
  }
@@ -1 +1 @@
1
- VERSION = "0.1.5"
1
+ VERSION = "0.1.6"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fibonacci
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-14 00:00:00.000000000 Z
12
+ date: 2011-12-17 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A Ruby gem for exploring Fibonacci series
15
15
  email: