This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Re: [PATCH] Re: Oops - Can't calculate our powers
[perl5.git] / t / op / pow.t
1 #!./perl -w
2 # Now they'll be wanting biff! and zap! tests too.
3
4 BEGIN {
5     chdir 't' if -d 't';
6     @INC = '../lib';
7     require './test.pl';
8 }
9
10 # This calcualtion ought to be within 0.001 of the right answer.
11 my $bits_in_uv = int (0.001 + log (~0+1) / log 2);
12
13 # 3**30 < 2**48, don't trust things outside that range on a Cray
14 # Likewise other 3 should not overflow 48 bits if I did my sums right.
15 my @pow = ([3,30,1e-14],
16            [4,32,0],
17            [5,20,1e-14],
18            [2.5, 10,,1e-14],
19            [-2, 69,0],
20            [-3, 30,0],
21 );
22 my $tests;
23 $tests += $_->[1] foreach @pow;
24
25 plan tests => 2 + $bits_in_uv + $tests;
26
27 # This gave positive 27 before change #20167
28 is((-3)**3, -27, "(negative int) ** (odd power) is negative");
29
30 # Ought to be 32, 64, 36 or something like that.
31
32 my $remainder = $bits_in_uv & 3;
33
34 cmp_ok ($remainder, '==', 0, 'Sanity check bits in UV calculation')
35     or printf "# ~0 is %d (0x%d) which gives $bits_in_uv bits\n", ~0, ~0;
36
37 # These are a lot of brute force tests to see how accurate $m ** $n is.
38 # Unfortunately rather a lot of perl programs expect 2 ** $n to be integer
39 # perfect, forgetting that it's a call to floating point pow() which never
40 # claims to deliver perfection.
41 foreach my $n (0..$bits_in_uv - 1) {
42     my $pow = 2 ** $n;
43     my $int = 1 << $n;
44     cmp_ok ($pow, '==', $int, "2 ** $n vs 1 << $n");
45 }
46
47 foreach my $pow (@pow) {
48     my ($base, $max, $range) = @$pow;
49     my $expect = 1;
50     foreach my $n (0..$max-1) {
51         my $got = $base ** $n;
52         within ($got, $expect, $range, "$base ** $n got[$got] expect[$expect]");
53         $expect *= $base;
54     }
55 }