fibonacci 0.1.5 → 0.1.6

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.
@@ -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: