File: 11-semiprimes.t

package info (click to toggle)
libmath-prime-util-perl 0.73-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 2,796 kB
  • sloc: perl: 24,676; ansic: 11,471; makefile: 26; python: 24
file content (107 lines) | stat: -rw-r--r-- 3,178 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#!/usr/bin/env perl
use strict;
use warnings;

use Test::More;
use Math::Prime::Util qw/semi_primes
                         semiprime_count semiprime_count_approx
                         nth_semiprime nth_semiprime_approx/;

my $extra = defined $ENV{EXTENDED_TESTING} && $ENV{EXTENDED_TESTING};
my $usexs = Math::Prime::Util::prime_get_config->{'xs'};

my @small_semis = (4,6,9,10,14,15,21,22,25,26,33,34,35,38,39,46,49,51,55,57,58,62,65,69,74,77,82,85,86,87,91,93,94,95);

my %small_range = (
  "11 to 13" => [],
  "10 to 10" => [10],
  "10 to 11" => [10],
  "10 to 12" => [10],
  "10 to 13" => [10],
  "10 to 14" => [10,14],
  "5 to 16" => [6,9,10,14,15],
  "4 to 11" => [4,6,9,10],
  "3 to 11" => [4,6,9,10],
  "2 to 11" => [4,6,9,10],
  "1 to 11" => [4,6,9,10],
  "0 to 11" => [4,6,9,10],
  "26 to 33" => [26,33],
  "25 to 34" => [25,26,33,34],
  "184279943 to 184280038" => [184279943,184279969,184280038],
  "184279944 to 184280037" => [184279969],
  "8589990147 to 8589990167" => [8589990149,8589990157,8589990166],
);

my %small_semis = (
    1234 =>   4497,
   12345 =>  51019,
  123456 => 573355,
);

my %big_semis = (
          "2147483648" =>         "14540737711",
       "4398046511104" =>      "36676111297003",
  "100000000000000000" => "1030179406403917981",
  "288230376151711744" => "3027432768282284351",
);

my %small_counts = (
    1234 =>   363,
   12345 =>  3217,
  123456 => 28589,
);

my %big_counts = (
             "100000000" =>           "17427258",
          "100000000000" =>        "13959990342",
       "100000000000000" =>     "11715902308080",
  "10000000000000000000" => "932300026230174178",
);

plan tests => 2
            + scalar(keys %small_range)
            + scalar(keys %small_semis)
            + scalar(keys %small_counts)
            + scalar(keys %big_counts)
            + scalar(keys %big_semis);

is_deeply( semi_primes($small_semis[-1]), \@small_semis, "semi_primes($small_semis[-1])" );

{
  my @tp = map { nth_semiprime($_) } 1 .. scalar(@small_semis);
  is_deeply( \@tp, \@small_semis, "nth_semiprime for small values" );
}

while (my($range, $expect) = each (%small_range)) {
  my($low,$high) = $range =~ /(\d+) to (\d+)/;
  is_deeply( semi_primes($low, $high), $expect, "semi_primes($low,$high) should return [@{$expect}]");
}

while (my($n, $spc) = each (%small_counts)) {
  is( semiprime_count($n), $spc, "semiprime_count($n) = $spc");
}
while (my($n, $nth) = each (%small_semis)) {
  SKIP: {
    skip "PP nth_semiprime is slow",1 unless $n < 10000 || $usexs || $extra;
    is( nth_semiprime($n), $nth, "nth_semiprime($n) = $nth");
  }
}


while (my($n, $spc) = each (%big_counts)) {
  # XS routine is within 0.00001.  PP within 0.002.
  cmp_closeto( semiprime_count_approx($n), $spc, 0.002 * abs($spc), "semiprime_count_approx($n) ~ $spc");
}

while (my($n, $nth) = each (%big_semis)) {
  # XS routine is within 0.00001.  PP within 0.001.
  cmp_closeto( nth_semiprime_approx($n), $nth, 0.001 * abs($nth), "nth_semiprime_approx($n) ~ $nth");
}

sub cmp_closeto {
  my $got = shift;
  my $expect = shift;
  my $tolerance = shift;
  my $message = shift;
  cmp_ok( abs($got - $expect), '<=', $tolerance, $message );
}