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