package Math::Name::To::Be::Determined; use warnings; use strict; our $VERSION = '0.01'; use vars qw(@ISA @EXPORT_OK %EXPORT_TAGS); use Exporter; @ISA = 'Exporter'; @EXPORT_OK = qw( clear_prime_cache is_prime primes_upto ); %EXPORT_TAGS = ( all => \@EXPORT_OK, ); { my ( @PRIMES, %IS_PRIME ); clear_prime_cache(); sub is_prime { my $number = shift; return 1 if $IS_PRIME{$number}; return if $number < $PRIMES[-1]; my $is_prime; for ( $PRIMES[-1] + 1 .. $number ) { # cache prime numbers if ( $is_prime = _is_prime($_) ) { push @PRIMES => $_; } } return $is_prime; } sub _is_prime { my $number = shift; return unless _is_integer($number); return 1 if $IS_PRIME{$number}; return unless $number > 2 and $number % 2; my $max = 1 + int $number**.5; for ( my $divisor = 3; $divisor < $max; $divisor += 2 ) { return unless $number % $divisor; } $IS_PRIME{$number} = 1; # cache it return 1; } sub primes_upto { my $number = shift; if ( $number > $PRIMES[-1] ) { # extend cache is_prime($number); } my (@primes); foreach my $i ( 0 .. @PRIMES ) { next if $number > $PRIMES[$i]; @primes = @PRIMES[ 0 .. $i - 1 ] if $i; last; } return wantarray ? @primes : \@primes; } sub clear_prime_cache { @PRIMES = _get_primes(); %IS_PRIME = map { $_ => 1 } @PRIMES; return; } } sub _is_integer { return shift =~ /^[-+]?\d+$/; } sub _get_primes { # list from Crypt::Primes # http://search.cpan.org/dist/Crypt-Primes/ return ( # huge list of all primes < 2^16 ); } 1;