File Coverage

blib/lib/Math/Fibonacci.pm
Criterion Covered Total %
statement 32 35 91.4
branch 9 12 75.0
condition n/a
subroutine 9 11 81.8
pod 4 8 50.0
total 54 66 81.8


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             #
3             # Computes the Fibonacci sequence using the fast algorithm: F(n) ~ g^n/sqrt(5),
4             # where g is the golden ratio and ~ stands for "take the nearest integer."
5             #
6             # Copyright (c) 1999-2000, Vipul Ved Prakash
7             # This code is free software distributed under the same license as Perl itself.
8             # $Id: Fibonacci.pm,v 1.5 2001/04/28 20:41:15 vipul Exp $
9              
10             package Math::Fibonacci;
11 2     2   16873 use strict;
  2         6  
  2         65  
12 2     2   11 use vars qw($VERSION @ISA @EXPORT_OK);
  2         3  
  2         113  
13 2     2   2154 use POSIX qw(log10 ceil floor);
  2         16971  
  2         17  
14             require Exporter;
15             @ISA = qw(Exporter);
16             ( $VERSION ) = '$Revision: 1.5 $' =~ /\s(\d+\.\d+)\s/;
17              
18             @EXPORT_OK = qw(term series decompose isfibonacci);
19              
20             sub g () { "1.61803398874989" } # golden ratio
21              
22 51     51 1 172 sub term { nearestint ((g ** shift) / sqrt(5)) } # nth term of the seq
23              
24 1     1 1 9 sub series { return map(term($_), 1..shift) } # n terms of the seq
25              
26              
27             sub decompose { # decomposes any integer into the sum of
28             # members of the fibonacci sequence.
29 1     1 1 10 my ($int) = @_;
30 1         5 my $sum = decomp ($int);
31 1         6 return @$sum;
32              
33             }
34              
35             sub decomp {
36 9     9 0 10 my ($a, $sum) = @_;
37 9         61 my $n = nearestint ((log10($a) + log10(sqrt(5)))/log10(g));
38 9         16 my $fibn = term($n);
39 9 100       29 if ( $fibn == $a ) { push @$sum, $a; return $sum }
  1 100       3  
  1 50       8  
40 4         5 elsif ( $fibn < $a ) { push @$sum, $fibn; decomp( $a-$fibn, $sum ) }
  4         24  
41 4         8 elsif ( $a < $fibn ) { my $fibn1 = term($n-1); push @$sum, $fibn1;
  4         5  
42 4         19 decomp( $a - $fibn1, $sum ) }
43             };
44              
45              
46             sub isfibonacci {
47            
48 14     14 1 1616 my $a = shift;
49 14         114 my $n = nearestint ((log10($a) + log10(sqrt(5)))/log10(g));
50 14 100       30 return $a == term($n) ? $n : 0;
51              
52             }
53              
54             sub nearestint {
55 74     74 0 81 my $v = shift;
56 74         119 my $f = floor($v); my $c = ceil($v);
  74         113  
57 74 100       284 ($v-$f) < ($c-$v) ? $f : $c;
58             }
59              
60              
61             # routines to implement term and series with the familiar additive algorithm.
62              
63 0 0   0 0   sub a_term { return $_[0] < 3 ? 1 : a_term($_[0]-1) + a_term ($_[0]-2) }
64              
65             sub a_series {
66 0     0 0   my @series = map(a_term($_), 1..shift);
67 0           \@series;
68             }
69              
70              
71             1;
72              
73              
74             =head1 NAME
75              
76             Math::Fibonacci - Fibonacci numbers.
77              
78             =head1 VERSION
79              
80             $Revision: 1.5 $
81              
82             =head1 SYNOPSIS
83              
84             use Math::Fibonacci qw(term series decompose);
85              
86             my $term = term ( 42 );
87             my @series = series ( 42 );
88             my @sum = decompose ( 65535 );
89              
90             =head1 DESCRIPTION
91              
92             This module provides a few functions related to Fibonacci numbers.
93              
94             =head1 EXPORTS ON REQUEST
95              
96             term(), series() decompose(), isfibonacci()
97              
98             =head1 FUNCTIONS
99              
100             =over 4
101              
102             =item B
103              
104             Returns the $n-th term of the Fibonacci sequence. The term is computed
105             using the fast algorithm: C, where g is the golden
106             ratio and ~ means "take the nearest integer".
107              
108             =item B
109              
110             Computes and returns the first $n Fibonacci numbers.
111              
112             =item B
113              
114             Decomposes $int into the sum of Fibonacci numbers. Returns the list of
115             Fibonacci numbers.
116              
117             =item B
118              
119             Returns the sequence number of $int if it is a Fibonacci number or a
120             non-true value if it is not.
121              
122             =head1 AUTHOR
123              
124             Vipul Ved Prakash, Email@vipul.netE
125              
126             =head1 LICENSE
127              
128             Copyright (c) 1999-2001, Vipul Ved Prakash.
129              
130             This code is free software; you can redistribute it and/or modify it under
131             the ARTISTIC license (a copy is included in the distribution) or under the
132             same terms as Perl itself.
133              
134             =cut
135