bitstring_prime_sieve_mpz.pl 1.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # License: GPLv3
  4. # Date: 09 July 2017
  5. # https://github.com/trizen
  6. # A decently fast bit-string sieve for prime numbers.
  7. # It's asymptotically faster than using Perl's arrays.
  8. # Also useful when memory is very restricted.
  9. use 5.010;
  10. use strict;
  11. use warnings;
  12. use Math::GMPz;
  13. sub bitstring_prime_sieve {
  14. my ($n) = @_;
  15. my $c = Math::GMPz::Rmpz_init_set_ui(1);
  16. Math::GMPz::Rmpz_setbit($c, $n + 1);
  17. my $bound = int(sqrt($n));
  18. for (my $i = 3 ; $i <= $bound ; $i += 2) {
  19. if (!Math::GMPz::Rmpz_tstbit($c, $i)) {
  20. for (my $j = $i * $i ; $j <= $n ; $j += $i << 1) {
  21. Math::GMPz::Rmpz_setbit($c, $j);
  22. }
  23. }
  24. }
  25. my @primes = (2);
  26. foreach my $k (1 .. ($n - 1) >> 1) {
  27. Math::GMPz::Rmpz_tstbit($c, ($k << 1) + 1) || push(@primes, ($k << 1) + 1);
  28. }
  29. return @primes;
  30. }
  31. my $n = shift(@ARGV) // 100;
  32. my @primes = bitstring_prime_sieve($n);
  33. say join(' ', @primes);
  34. say "PI($n) = ", scalar(@primes);