xref: /onnv-gate/usr/src/cmd/perl/5.8.4/distrib/t/op/pow.t (revision 0:68f95e015346)
1*0Sstevel@tonic-gate#!./perl -w
2*0Sstevel@tonic-gate# Now they'll be wanting biff! and zap! tests too.
3*0Sstevel@tonic-gate
4*0Sstevel@tonic-gateBEGIN {
5*0Sstevel@tonic-gate    chdir 't' if -d 't';
6*0Sstevel@tonic-gate    @INC = '../lib';
7*0Sstevel@tonic-gate    require './test.pl';
8*0Sstevel@tonic-gate}
9*0Sstevel@tonic-gate
10*0Sstevel@tonic-gate# This calcualtion ought to be within 0.001 of the right answer.
11*0Sstevel@tonic-gatemy $bits_in_uv = int (0.001 + log (~0+1) / log 2);
12*0Sstevel@tonic-gate
13*0Sstevel@tonic-gate# 3**30 < 2**48, don't trust things outside that range on a Cray
14*0Sstevel@tonic-gate# Likewise other 3 should not overflow 48 bits if I did my sums right.
15*0Sstevel@tonic-gatemy @pow = ([  3, 30, 1e-14],
16*0Sstevel@tonic-gate           [  4, 32,     0],
17*0Sstevel@tonic-gate           [  5, 20, 1e-14],
18*0Sstevel@tonic-gate           [2.5, 10, 1e-14],
19*0Sstevel@tonic-gate           [ -2, 69,     0],
20*0Sstevel@tonic-gate           [ -3, 30, 1e-14],
21*0Sstevel@tonic-gate);
22*0Sstevel@tonic-gatemy $tests;
23*0Sstevel@tonic-gate$tests += $_->[1] foreach @pow;
24*0Sstevel@tonic-gate
25*0Sstevel@tonic-gateplan tests => 13 + $bits_in_uv + $tests;
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate# (-3)**3 gave 27 instead of -27 before change #20167.
28*0Sstevel@tonic-gate# Let's test the other similar edge cases, too.
29*0Sstevel@tonic-gateis((-3)**0, 1,   "negative ** 0 = 1");
30*0Sstevel@tonic-gateis((-3)**1, -3,  "negative ** 1 = self");
31*0Sstevel@tonic-gateis((-3)**2, 9,   "negative ** 2 = positive");
32*0Sstevel@tonic-gateis((-3)**3, -27, "(negative int) ** (odd power) is negative");
33*0Sstevel@tonic-gate
34*0Sstevel@tonic-gate# Positives shouldn't be a problem
35*0Sstevel@tonic-gateis(3**0, 1,      "positive ** 0 = 1");
36*0Sstevel@tonic-gateis(3**1, 3,      "positive ** 1 = self");
37*0Sstevel@tonic-gateis(3**2, 9,      "positive ** 2 = positive");
38*0Sstevel@tonic-gateis(3**3, 27,     "(positive int) ** (odd power) is positive");
39*0Sstevel@tonic-gate
40*0Sstevel@tonic-gate# And test order of operations while we're at it
41*0Sstevel@tonic-gateis(-3**0, -1);
42*0Sstevel@tonic-gateis(-3**1, -3);
43*0Sstevel@tonic-gateis(-3**2, -9);
44*0Sstevel@tonic-gateis(-3**3, -27);
45*0Sstevel@tonic-gate
46*0Sstevel@tonic-gate
47*0Sstevel@tonic-gate# Ought to be 32, 64, 36 or something like that.
48*0Sstevel@tonic-gate
49*0Sstevel@tonic-gatemy $remainder = $bits_in_uv & 3;
50*0Sstevel@tonic-gate
51*0Sstevel@tonic-gatecmp_ok ($remainder, '==', 0, 'Sanity check bits in UV calculation')
52*0Sstevel@tonic-gate    or printf "# ~0 is %d (0x%d) which gives $bits_in_uv bits\n", ~0, ~0;
53*0Sstevel@tonic-gate
54*0Sstevel@tonic-gate# These are a lot of brute force tests to see how accurate $m ** $n is.
55*0Sstevel@tonic-gate# Unfortunately rather a lot of perl programs expect 2 ** $n to be integer
56*0Sstevel@tonic-gate# perfect, forgetting that it's a call to floating point pow() which never
57*0Sstevel@tonic-gate# claims to deliver perfection.
58*0Sstevel@tonic-gateforeach my $n (0..$bits_in_uv - 1) {
59*0Sstevel@tonic-gate    my $pow = 2 ** $n;
60*0Sstevel@tonic-gate    my $int = 1 << $n;
61*0Sstevel@tonic-gate    cmp_ok ($pow, '==', $int, "2 ** $n vs 1 << $n");
62*0Sstevel@tonic-gate}
63*0Sstevel@tonic-gate
64*0Sstevel@tonic-gateforeach my $pow (@pow) {
65*0Sstevel@tonic-gate    my ($base, $max, $range) = @$pow;
66*0Sstevel@tonic-gate    my $expect = 1;
67*0Sstevel@tonic-gate    foreach my $n (0..$max-1) {
68*0Sstevel@tonic-gate        my $got = $base ** $n;
69*0Sstevel@tonic-gate        within ($got, $expect, $range, "$base ** $n got[$got] expect[$expect]");
70*0Sstevel@tonic-gate        $expect *= $base;
71*0Sstevel@tonic-gate    }
72*0Sstevel@tonic-gate}
73