The following will speed up your calculation significantly:
# Doing $x ** $y can result in very large numbers,
# But if what you want it ( $x ** $y ) % $m, then
# you can pull the modulo into the products and keep
# your numbers smaller.
sub ModuloPwr
{
my($base,$pwr,$mod) = @_;
return 1 if $pwr < 1;
# I probably don't need the 0.1, but doesn't hurt.
my $result = ModuloPwr($base, int(0.1 + $pwr/2), $mod);
$result = ($result * $result) % $mod;
if ($pwr%2) {
$result = ( $result * $base ) % $mod;
}
return $result;
}
However there appears to be a bug somewhere. It works fine
for small primes, but for instance 97397 is reported not a prime, while it is. (I checked and double-checked. My change does not cause the issue.)
UPDATE
I am a moron. The bug is simple and obvious. Square then reduce modulo the prime works fine until the prime is large enough to go outside of native integer arithmetic. At that point things go haywire.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.
|