#!/usr/bin/perl

sub exp_slow {
    use integer;
    my ( $result, $i, $j ) = (1, @_);
    $result *= $i while $j--;
    return $result;
}

sub exp_recurse {
    use integer;
    my ( $bottom, $i, $j ) = ( 1, @_ );
    return $i - $i + 1 if $j == 0;
    return $i          if $j == 1;
    if ( $j % 2 ) {                      # Is $j odd?
        $bottom = $i;
        --$j;
    }
    my $halftop = exp_recurse( $i, $j/2 );
    return $halftop * $halftop * $bottom;
}

sub exp_fast {
    use integer;
    my ( $i, $j ) = @_;
    my $result    = $i-$i+1;
    my $pow2      = $i;

    while ( $j ) {
        if ( $j%2 ) {
            $result = $pow2 * $result;
            $j--;
        }
        $j /= 2;
        $pow2 = $pow2 * $pow2;
    }
    return $result;
}

print exp_slow(5, 7), "\n";
print exp_recurse(5, 7), "\n";
print exp_fast(5, 7), "\n";
