Back to mersenne-aries.sili.net main page
credit.php:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
    <title>GIMPS PrimeNet CPU credit calculator</title>
    <link rel="stylesheet" href="/style.css" type="text/css">
    <script type="text/javascript">
        function checkCreditForm(theform) {
            return true;
        }
    </script>
</head>
<body>
<a href="/">Back to <i>mersenne-aries.sili.net</i> main page</a>
<hr size="1">
<?php

if (@$_REQUEST['showsource']) {
    
$filestoshow = array(basename(__FILE__), 'functions.inc.php''cpucredit.inc.php');
    foreach (
$filestoshow as $key => $value) {
        echo 
htmlentities($value).':<blockquote style="border: 1px solid #000000; padding: 10px;">';
        
highlight_file($value);
        echo 
'</blockquote>';
    }
    exit;
}
echo 
'<a href="'.$_SERVER['PHP_SELF'].'?showsource=1" style="font-size: 8pt;">show source</a><hr noshade size="1">';

///////////////////////////////////////////////////////////////////////////
require_once('functions.inc.php');
///////////////////////////////////////////////////////////////////////////

if (!isset($_REQUEST['b1']) && !isset($_REQUEST['b2'])) {
    if (@
$_REQUEST['guess'] == 'n') {
        
// guess for never-been-LL'd
        
$_REQUEST['b1'] = B1bound(@$_REQUEST['exponent'], false);
        
$_REQUEST['b2'] = $_REQUEST['b1'] * 25;
    } elseif (@
$_REQUEST['guess'] == 'y') {
        
// guess for already-been-LL'd-once
        
$_REQUEST['b1'] = B1bound(@$_REQUEST['exponent'], true);
        
$_REQUEST['b2'] = $_REQUEST['b1'] * 20;
    }
}

echo 
'<h3>Estimate CPU credit for PrimeNet assignments</h3>';
echo 
'<form method="get" action="'.$_SERVER['PHP_SELF'].'" name="form1" onSubmit="return checkCreditForm(this);">';
echo 
'<table border="0">';
$worktypes = array(''=>'--select one--''LL'=>'Lucas-Lehmer''TF'=>'Trial Factoring''P-1'=>'P-1 Factoring''ECM'=>'ECM Factoring');
echo 
'<tr><td>Work Type:<td><select name="worktype">';
foreach (
$worktypes as $key => $value) {
    echo 
'<option value="'.htmlentities($keyENT_QUOTES).'"'.(($key == @$_REQUEST['worktype']) ? ' selected="selected"' '').'>'.htmlentities($valueENT_QUOTES).'</option>';
}
echo 
'</select></td></tr>';
echo 
'<tr><td>Exponent:</td>       <td>M<input type="text" size="9"  name="exponent"  value="'.htmlentities(@$_REQUEST['exponent'], ENT_QUOTES).'"> (or F<input type="text" size="2" name="f_exponent" value="'.htmlentities(@$_REQUEST['f_exponent'], ENT_QUOTES).'">)</td></tr>';
echo 
'<tr><td>B1:</td>             <td> <input type="text" size="20" name="b1"        value="'.htmlentities(@$_REQUEST['b1'],       ENT_QUOTES).'"></td></tr>';
echo 
'<tr><td>B2:</td>             <td> <input type="text" size="20" name="b2"        value="'.htmlentities(@$_REQUEST['b2'],       ENT_QUOTES).'"></td></tr>';
echo 
'<tr><td>ECMcurves:</td>      <td> <input type="text" size="3"  name="numcurves" value="'.htmlentities(@$_REQUEST['numcurves'],       ENT_QUOTES).'"></td></tr>';
echo 
'<tr><td>Factor:</td>         <td> <input type="text" size="20" name="factor"    value="'.htmlentities(@$_REQUEST['factor'],   ENT_QUOTES).'"></td></tr>';
echo 
'<tr><td>Factoring Range:</td><td> <input type="text" size="3" name="frombits"   value="'.htmlentities(@$_REQUEST['frombits'], ENT_QUOTES).'"> to <input type="text" size="3" name="tobits" value="'.htmlentities(@$_REQUEST['tobits'], ENT_QUOTES).'"></td></tr>';
echo 
'<tr><td colspan="2"><input type="submit" name="submitbutton" value="Calculate"></td></tr>';
echo 
'</table>';
echo 
'</form>';

$forcenumeric = array('exponent''f_exponent''factor''frombits''tobits''b1''b2''numcurves');
foreach (
$forcenumeric as $key => $value) {
    
$_REQUEST[$value] = eregi_replace('[^0-9]''', @$_REQUEST[$value]);
}

if (
$_REQUEST['f_exponent']) {
    if (
$_REQUEST['f_exponent'] <= 30) {
        echo 
'<div style="color: red;">Fermat exponent F'.$_REQUEST['f_exponent'].' roughly translated to M(2^'.$_REQUEST['f_exponent'].') = M'.pow(2$_REQUEST['f_exponent']).' for credit-calculation purposes. Credit may be off by up to 25%</div>';
        
$_REQUEST['exponent'] = pow(2$_REQUEST['f_exponent']);
    } else {
        echo 
'Fermat exponents larger than 30 not currently supported';
        exit;
    }
}
if (
$_REQUEST['exponent'] && @$_REQUEST['worktype']) {
    echo 
'<hr>';
    
$savedwork = array(0=>array(),1=>array());
    
$thisWorkGHzDays 0;
    
$thisSaveGHzDays 0;
    switch (
$_REQUEST['worktype']) {
        case 
'LL':
            if (
$_REQUEST['exponent']) {
                
// is OK
            
} else {
                echo 
'ERROR: "exponent" must be specified';
                exit;
            }

            
$thisWorkGHzDays CalcGHzDaysLL($_REQUEST['exponent']);

            
$description 'Lucas-Lehmer test on "'.htmlentities($_REQUEST['exponent']).'"';
            
$work_done   'LL test ('.number_format(fft_timings_lookup($_REQUEST['exponent'], -1) / 10240'.''').'K FFT)';
            break;

        case 
'TF':
            if (
$_REQUEST['factor'] || ($_REQUEST['frombits'] && $_REQUEST['tobits'])) {
                
// is OK
            
} else {
                echo 
'ERROR: one of ("factor" or ("tobits" and "frombits")) must be specified';
                exit;
            }

            
$thisWorkGHzDays CalcGHzDaysTrialFactor($_REQUEST['exponent'], $_REQUEST['frombits'], $_REQUEST['tobits'], $_REQUEST['factor']);

            if (
$_REQUEST['factor']) {
                
$maxbits max($_REQUEST['tobits'], FactorBits($_REQUEST['exponent']));
                if (
$maxbits $_REQUEST['tobits']) {
                    
$savedstartbits = ($_REQUEST['factor'] ? ceil(log($_REQUEST['factor'], 2)) : $_REQUEST['tobits']);
//var_dump($savedstartbits);
                    
if ($savedstartbits $maxbits) {
                        
$thissavedGHzDays CalcGHzDaysTrialFactor($_REQUEST['exponent'], $savedstartbits$maxbits);
                        
$savedwork[0][] = number_format($thissavedGHzDays3);
                        
$savedwork[1][] = 'GHz-days: TF (from 2^'.$savedstartbits.' to 2^'.$maxbits.')';
                        
$thisSaveGHzDays += $thissavedGHzDays;
                    }
                }
                
$thissavedGHzDays CalcGHzDaysPminus1($_REQUEST['exponent'], falsefalse);
                
$savedwork[0][] = number_format($thissavedGHzDays3);
                
$savedwork[1][] = 'GHz-days: P-1 (B1='.B1bound($_REQUEST['exponent']).',B2='.(25 B1bound($_REQUEST['exponent'])).')';
                
$thisSaveGHzDays += $thissavedGHzDays;

                
$thissavedGHzDays CalcGHzDaysLL($_REQUEST['exponent']);
                
$savedwork[0][] = number_format($thissavedGHzDays3);
                
$savedwork[1][] = 'GHz-days (2x LL tests)';
                
$thisSaveGHzDays += $thissavedGHzDays;
            }

            
$description 'Trial Factoring on "M'.htmlentities($_REQUEST['exponent']).'"'.($_REQUEST['factor'] ? ' with '.number_format(log($_REQUEST['factor'], 2), 2).'-bit factor "'.$_REQUEST['factor'].'"' 'from 2^'.$_REQUEST['frombits'].' to 2^'.$_REQUEST['tobits']);
            
$work_done   'TF M'.htmlentities($_REQUEST['exponent']).($_REQUEST['factor'] ? ' with '.ceil(log($_REQUEST['factor'], 2)).'-bit factor' ' from 2^'.htmlentities($_REQUEST['frombits']).' to 2^'.htmlentities($_REQUEST['tobits']));
            break;

        case 
'P-1':
            if (
$_REQUEST['factor'] || ($_REQUEST['b1'] && $_REQUEST['b2'])) {
                
// is OK
            
} else {
                echo 
'ERROR: one of ("factor" or ("b1" and "b2")) must be specified';
                exit;
            }

            
$_REQUEST['b1'] = ($_REQUEST['b1'] ? $_REQUEST['b1'] : false);
            
$_REQUEST['b2'] = ($_REQUEST['b2'] ? $_REQUEST['b2'] : false);
            
$thisWorkGHzDays CalcGHzDaysPminus1($_REQUEST['exponent'], $_REQUEST['b1'], $_REQUEST['b2']);

            if (
$_REQUEST['factor']) {
                
$maxbits max($_REQUEST['tobits'], FactorBits($_REQUEST['exponent']));
                if (
$maxbits $_REQUEST['tobits']) {
                    
$savedstartbits = ($_REQUEST['factor'] ? ceil(log($_REQUEST['factor'], 2)) : $_REQUEST['tobits']);
                    if (
$savedstartbits $_REQUEST['tobits']) {
                        
$thissavedGHzDays CalcGHzDaysTrialFactor($_REQUEST['exponent'], $savedstartbits$maxbits);
                        
$savedwork[0][] = number_format($thissavedGHzDays3);
                        
$savedwork[1][] = 'GHz-days: TF (from 2^'.$savedstartbits.' to 2^'.$maxbits.')';
                        
$thisSaveGHzDays += $thissavedGHzDays;
                    }
                }
                
$thissavedGHzDays CalcGHzDaysLL($_REQUEST['exponent']);
                
$savedwork[0][] = number_format($thissavedGHzDays3);
                
$savedwork[1][] = 'GHz-days (2x LL tests)';
                
$thisSaveGHzDays += $thissavedGHzDays;
            }
            
$description 'P-1 Factoring on "'.htmlentities($_REQUEST['exponent']).'"'.($_REQUEST['factor'] ? ' with '.number_format(log($_REQUEST['factor'], 2), 2).'-bit factor "'.$_REQUEST['factor'].'"' ' (B1='.$_REQUEST['b1'].', B2='.$_REQUEST['b2'].')');
            
$work_done   'P-1 M'.htmlentities($_REQUEST['exponent']).($_REQUEST['factor'] ? ' with '.ceil(log($_REQUEST['factor'], 2)).'-bit factor' ' (B1='.$_REQUEST['b1'].', B2='.$_REQUEST['b2'].')');
            break;

        case 
'ECM':
            if (
$_REQUEST['factor'] || ($_REQUEST['b1'] && $_REQUEST['b2'] && $_REQUEST['numcurves'])) {
                
// is OK
            
} else {
                echo 
'ERROR: one of ("factor" or ("b1" and "b2" and "numcurves")) must be specified';
                exit;
            }

            
$_REQUEST['b1'] = ($_REQUEST['b1'] ? $_REQUEST['b1'] : false);
            
$_REQUEST['b2'] = ($_REQUEST['b2'] ? $_REQUEST['b2'] : false);
            
$thisWorkGHzDays CalcGHzDaysECM($_REQUEST['exponent'], $_REQUEST['numcurves'], $_REQUEST['b1'], $_REQUEST['b2']);

            if (
$_REQUEST['factor']) {
                
// no work saved
            
}

            
$description 'ECM Factoring on "'.htmlentities($_REQUEST['exponent']).'"'.($_REQUEST['factor'] ? ' with '.number_format(log($_REQUEST['factor'], 2), 2).'-bit factor "'.$_REQUEST['factor'].'"' ' (curves='.$_REQUEST['numcurves'].', B1='.$_REQUEST['b1'].', B2='.$_REQUEST['b2'].')');
            
$work_done   'ECM M'.htmlentities($_REQUEST['exponent']).($_REQUEST['factor'] ? ' with '.ceil(log($_REQUEST['factor'], 2)).'-bit factor' ' (curves='.$_REQUEST['numcurves'].', B1='.$_REQUEST['b1'].', B2='.$_REQUEST['b2'].')');
            break;

        default:
            echo 
'ERROR: Invalid worktype';
            exit;
            break;
    }

    echo 
$description.':<br>';
    echo 
'<table border="1" cellspacing="0" cellpadding="3">';
    echo 
'<tr><th colspan="2">Work credit</th><th colspan="2">Work saved</th></tr>';
    echo 
'<tr><td colspan="2">'.$work_done.'</td>';
    if (!empty(
$savedwork[0])) {
        echo 
'<td align="right" style="text-align: right; font-family: monospace;">'.implode('<br>'$savedwork[0]).'</td>';
        echo 
'<td>'.implode('<br>'$savedwork[1]).'</td>';
    } else {
        echo 
'<td colspan="2" align="center"><i>none</i>';
    }
    echo 
'</td></tr>';
    echo 
'<tr>';

    echo 
'<td align="right" style="text-align: right; font-family: monospace;">'.(($thisWorkGHzDays 0.00001) ? sprintf('%.3e'$thisWorkGHzDays) : number_format($thisWorkGHzDays6)).'<br><span style="color: #999999;">'.(($thisWorkGHzDays 0.00001) ? sprintf('%.3e'GHzDays2P90years($thisWorkGHzDays)) : number_format(GHzDays2P90years($thisWorkGHzDays), 6)).'</span></td><td>GHz-days<br><span style="color: #999999;">P90years</span></td>';
    echo 
'<td align="right" style="text-align: right; font-family: monospace;">'.number_format($thisSaveGHzDays3).'<br><span style="color: #999999;">'.number_format(GHzDays2P90years($thisSaveGHzDays), 3).'</span></td><td>GHz-days<br><span style="color: #999999;">P90years</span></td>';
    echo 
'</tr>';
    echo 
'</table>';
}

?>
</body>
</html>
functions.inc.php:
<?php
require_once('db.inc.php');
error_reporting(E_ALL);
ini_set('display_errors''1');

define('STATS_HTML_CACHE_DIR'dirname(__FILE__).'/statsHTMLcache/');
///////////////////////////////////////////////////////////////////////////

function filesize_remote($remotefile$timeout=10) {
    static 
$filesize_cache = array();
    if (!@
$filesize_cache[$remotefile]) {
        
$filesize_cache[$remotefile] = false;
        
$url parse_url($remotefile);
        if (
$fp = @fsockopen($url['host'], ($url['port'] ? $url['port'] : 80), $errno$errstr$timeout)) {
            
fwrite($fp'HEAD '.@$url['path'].@$url['query'].' HTTP/1.0'."\r\n");
            
fwrite($fp'Host: '.@$url['host']."\r\n");
            if (@
$url['user'] || @$url['pass']) {
                
fwrite($fp'Authorization: Basic '.base64_encode($url['user'].':'.$url['pass'])."\r\n");
            }
            
fwrite($fp"\r\n");
            
stream_set_timeout($fp$timeout);
            while (!
feof($fp)) {
                
$headerline fgets($fp4096);
                if (
eregi('^Content-Length: (.*)'$headerline$matches)) {
                    
$filesize_cache[$remotefile] = intval($matches[1]);
                    break;
                }
            }
            
fclose ($fp);
        }
    }
    return 
$filesize_cache[$remotefile];
}

function 
filedate_remote($remotefile$timeout=10) {
    static 
$filedate_cache = array();
    if (!@
$filedate_cache[$remotefile]) {
        
$filedate_cache[$remotefile] = false;
        
$url parse_url($remotefile);
        if (
$fp = @fsockopen($url['host'], ($url['port'] ? $url['port'] : 80), $errno$errstr$timeout)) {
            
fwrite($fp'HEAD '.@$url['path'].@$url['query'].' HTTP/1.0'."\r\n");
            
fwrite($fp'Host: '.@$url['host']."\r\n");
            if (@
$url['user'] || @$url['pass']) {
                
fwrite($fp'Authorization: Basic '.base64_encode($url['user'].':'.$url['pass'])."\r\n");
            }
            
fwrite($fp"\r\n");
            
stream_set_timeout($fp$timeout);
            while (!
feof($fp)) {
                
$headerline fgets($fp4096);
                if (
eregi('^Last-Modified: (.*)'$headerline$matches)) {
                    
$filedate_cache[$remotefile] = strtotime($matches[1]) - date('Z');
                    break;
                }
            }
            
fclose($fp);
        }
    }
    return 
$filedate_cache[$remotefile];
}

function 
P90years2GHzDays($P90years) {
    
// straight from George :)
    // http://www.mersenneforum.org/showpost.php?p=133207&postcount=3
    // One core of a C2D = 1.68 P4
    // A P4 = 3.44 PIIs
    // A PII = 1.12 Pentium
    // Thus, a P-90 CPU year = 365 days * 1 C2GHD * (90MHz / 1000MHz) / 1.68 / 3.44 / 1.12 = 5.075 C2GHDs
    
return $P90years 5.075;
}

function 
GHzDays2P90years($GHzDays) {
    
// straight from George :)
    // http://www.mersenneforum.org/showpost.php?p=133207&postcount=3
    // One core of a C2D = 1.68 P4
    // A P4 = 3.44 PIIs
    // A PII = 1.12 Pentium
    // Thus, a P-90 CPU year = 365 days * 1 C2GHD * (90MHz / 1000MHz) / 1.68 / 3.44 / 1.12 = 5.075 C2GHDs
    
return $GHzDays 5.075;
}

function 
CalcGHzDaysPminus1($exponent$b1=false$b2=false) {
    if (
$b1 === false) {
        
//$alreadyLLd = true; // most Mersenne-aries work will be done with Pfactor=exp,bits,1
        
$alreadyLLd false;
        
$b1 B1bound($exponent$alreadyLLd);
    }
    if (
$b2 == false) {
        
$b2 $b1 25// rough approximation of default auto-selection
    
} elseif ($b2 $b1) {
        
$b2 $b1;
    }
    require_once(
'cpucredit.inc.php');
    return 
credit_cpu_PM1_factoring($exponent0$b1$b2);
}

function 
CalcP90yearsPminus1($exponent$b1=false$b2=false) {
    return 
GHzDays2P90years(CalcGHzDaysPminus1($exponent$b1$b2));
}

function 
CalcGHzDaysECM($exponent$curves_run$b1$b2) {
    require_once(
'cpucredit.inc.php');
    return 
credit_cpu_ECM($exponent0$curves_run$b1$b2);
}

function 
CalcP90yearsECM($exponent$curves_run$b1$b2) {
    return 
GHzDays2P90years(CalcGHzDaysECM($exponent$curves_run$b1$b2));
}

function 
CalcGHzDaysLL($exponent) {
    require_once(
'cpucredit.inc.php');
    return 
credit_cpu_LL($exponent0);
}

function 
CalcP90yearsLL($exponent) {
    return 
GHzDays2P90years(CalcGHzDaysLL($exponent));
}

function 
BitsInFactor($factor$intversion=false) {
    return (
$intversion ceil(log($factor2)) : log($factor2));
}

function 
ExponentFactorThreshold() {
    static 
$ExponentThreshold = array(

        
// These breakeven points we're calculated on a 2.0 GHz P4 Northwood:
        
516000000 => 80,
        
420400000 => 79,
        
337400000 => 78,
        
264600000 => 77,
        
227300000 => 76,
        
186400000 => 75,
        
147500000 => 74,
        
115300000 => 73,
         
96830000 => 72,
         
75670000 => 71,
         
58520000 => 70,
         
47450000 => 69,
         
37800000 => 68,
         
29690000 => 67,
         
23390000 => 66,

         
// These breakevens we're calculated a long time ago on unknown hardware:
         
13380000 => 65,
          
8250000 => 64,
          
6515000 => 63,
          
5160000 => 62,
          
3960000 => 61,
          
2950000 => 60,
          
2360000 => 59,
          
1930000 => 58,
          
1480000 => 57,
          
1000000 => 56,
                
=> 40,

        
// OLD values from the before-time
        //79300000=>72, // Prime95 can't currently handle exponents bigger than this...
        //71000000=>72,
        //57020000=>71,
        //44150000=>70,
        //35100000=>69,
        //28130000=>68,
        //21590000=>67,
        //17850000=>66,
    
);
    return 
$ExponentThreshold;
}

function 
FactorBits($exponent) {
    
$ExponentThreshold ExponentFactorThreshold();
    
$factorbits 0;
    foreach (
$ExponentThreshold as $limit => $bits) {
        if (
$exponent >= $limit) {
            
$factorbits $bits;
            break;
        }
    }
    return 
$factorbits;
}

function 
CalcGHzDaysTrialFactor($exponent$frombits=0$limit=false$factor='') {
    if (
$limit === false) {
        
// how far will Prime95 factor this exponent by default
        
$limit FactorBits($exponent);
    }
    if (!
$frombits && !$factor) {
        
// this is a hack for pre-v25 which didn't always report starting point of TF
        // most trial factoring is done from <whatever-the-current-level-is> to
        // the reported bit depth, but it doesn't report the current level. So guess :)
        
if ($limit <= 58) {
            
$frombits 32;         // anything factored to low bit depths started from nothing, or close-to-nothing (CPU time to factor from 2^0 to 2^32 is insignificant)
        
} else {
            
$frombits $limit 1// assume most submitted results will be LMH results increasing factor depth by 1 level
        
}
    }
    require_once(
'cpucredit.inc.php');
    if (
$factor) {
        
$frombits floor(log($factor2));
        return 
credit_cpu_TF_factor_p95($exponent$factor$frombits);
    } else {
        return 
credit_cpu_TF_no_factor($exponent$frombits$limit);
    }
}

function 
CalcP90yearsTrialFactor($exponent$frombits=0$limit=false$factor='') {
    return 
GHzDays2P90years(CalcGHzDaysTrialFactor($exponent$frombits$limit$factor));
}

function 
B1bound($exponent$alreadyLLd=false) {
    
// formulae taken from Excel graph of actual values from Prime95
    // it's a little off around FFT size changes, but close enough
    
$exp $exponent 1000000;
    if (
$alreadyLLd) {
        
//$B1 = (-11 * $exp * $exp) + (5800 * $exp);   // projection data up to 79M
        
$B1 = (-1.3309 $exp $exp) + (5232 $exp); // updated formula from 2008-12-13 with projection data up to 500M
    
} else {
        
//$B1 = (-24.529 * $exp * $exp) + (12434 * $exp); // projection data up to 79M
        
$B1 = (-3.2698 $exp $exp) + (11182 $exp);   // updated formula from 2008-12-13 with projection data up to 500M
    
}
    return 
round($B1 5000) * 5000;
}

function 
B2bound($exponent$alreadyLLd=false) {
    return 
B1bound($exponent$alreadyLLd) * ($alreadyLLd 20 25);
}


function 
DickmansFunction($x) {
    static 
$savedF = array(
        
0000003.3513e-2155.63754e-2084.00865e-201,
        
1.65407e-1944.53598e-1888.93587e-1821.33115e-175,
        
1.55557e-1691.46609e-1631.13896e-1577.42296e-152,
        
3.80812e-1461.56963e-1405.32886e-1351.51923e-129,
        
3.69424e-1247.76066e-1191.42371e-1132.30187e-108,
        
3.30619e-1034.24793e-0984.80671e-0934.78516e-088,
        
4.22768e-0833.33979e-0782.37455e-0731.52822e-068,
        
8.94846e-0644.78909e-0594.65696e-0574.49802e-0554.31695e-053,
        
4.07311e-0513.81596e-0493.61043e-0471.73046e-0458.26375e-044,
        
3.9325e-0421.86471e-0408.8102e-0394.14402e-0371.99497e-035,
        
1.83001e-0341.59023e-0331.45505e-0321.24603e-0311.15674e-030,
        
9.70832e-0309.23876e-0294.20763e-0284.24611e-0271.61371e-026,
        
6.59556e-0263.17069e-0251.12205e-0244.65874e-0242.01267e-023,
        
6.2941e-0233.02604e-0227.84622e-0222.3526e-0216.7049e-021,
        
1.88634e-0204.59378e-0201.37233e-0194.00682e-0198.34209e-019,
        
2.21612e-0184.84252e-0181.02457e-0172.03289e-0174.07704e-017,
        
1.33778e-0162.4263e-0164.14981e-0167.0383e-0161.20511e-015,
        
3.85644e-0156.52861e-0151.06563e-0141.67897e-0142.79916e-014,
        
4.54319e-0149.83296e-0141.66278e-0132.61858e-0134.03872e-013,
        
5.98967e-0131.09674e-0121.70553e-0122.56573e-0123.72723e-012,
        
6.14029e-0129.33636e-0121.36469e-0111.89881e-0112.68391e-011,
        
4.12016e-0115.94394e-0118.43746e-0111.12903e-0101.66987e-010,
        
2.36959e-0103.11726e-0104.28713e-0105.90781e-0107.79892e-010,
        
1.05264e-0091.4016e-0091.87506e-0092.42521e-0093.14508e-009,
        
4.38605e-0095.43307e-0096.96737e-0098.84136e-0091.16286e-008,
        
1.42343e-0081.79697e-0082.30867e-0082.88832e-0083.52583e-008,
        
4.31032e-0085.46444e-0086.66625e-0088.06132e-0081.00085e-007,
        
1.20952e-0071.4816e-0071.80608e-0072.13125e-0072.5324e-007,
        
3.094e-0073.64545e-0074.31692e-0075.19078e-0076.03409e-007,
        
7.21811e-0078.53856e-0079.71749e-0071.13949e-0061.37042e-006,
        
1.53831e-0061.79066e-0062.15143e-0062.40216e-0062.76872e-006,
        
3.20825e-0063.61263e-0064.21315e-0064.76404e-0065.43261e-006,
        
6.2041e-0066.96243e-0067.94979e-0068.89079e-0061.01387e-005,
        
1.13376e-0051.2901e-0051.44183e-0051.59912e-0051.79752e-005,
        
1.99171e-0052.22665e-0052.47802e-0052.7678e-0053.0492e-005,
        
3.34189e-0053.71902e-0054.12605e-0054.54706e-0054.98411e-005,
        
5.48979e-0056.06015e-0056.61278e-0057.22258e-0057.97193e-005,
        
8.66574e-0059.48075e-0050.000103210.0001124790.000121776,
        
0.0001333440.0001440230.0001566670.0001683180.000183192,
        
0.0001965270.000213950.0002283890.0002492230.000264372,
        
0.0002893840.0003057070.0003339920.0003532870.000379868,
        
0.0004082740.000436380.0004653190.0004965040.000530376,
        
0.0005660080.0006026210.0006422860.0006845430.000723853,
        
0.0007726550.0008194180.0008685330.0009203990.000975529,
        
0.001031880.001094780.001157770.001220870.00128857,
        
0.001362880.001435570.001517140.001597470.00167572,
        
0.001765560.001861990.001950630.002052390.00216102,
        
0.002256980.002369620.002491450.002596360.00272455,
        
0.002870060.002975450.003123460.00326340.00340298,
        
0.003558270.003711950.003872880.004047250.00420016,
        
0.004397460.004563320.004759360.004957020.00514683,
        
0.005352840.005579040.005780840.006010280.00623082,
        
0.006477650.006734990.006965530.007225290.00748878,
        
0.007755370.008032710.008321990.008616120.00889863,
        
0.009198760.009533430.009854650.01019930.01050420.0108325,
        
0.01120190.01159010.01192950.01230090.01271910.0130652,
        
0.01348550.01391870.01429290.01475410.01513540.0156087,
        
0.01605720.01653820.01696690.01746930.01794600.0184202,
        
0.01895550.01943360.02001070.02048630.02102420.0216053,
        
0.02213610.02268580.02326930.02390270.02447790.025081,
        
0.02571690.02630590.02692130.02755330.02820650.0289028,
        
0.02956700.03022680.03091930.03166190.03231470.0330398,
        
0.03381240.03452670.03530380.03609470.03682880.0376202,
        
0.03837840.03918940.03996840.04081480.04164030.042545,
        
0.04336620.04424980.04510030.04603500.04688010.0478059,
        
0.04874420.04966470.05057520.05151230.05247920.0534474,
        
0.05446820.05545790.05650240.05746190.05847570.0595123,
        
0.06059880.06158740.06271900.06378760.06488300.0659551,
        
0.06705670.06812560.06927640.07045840.07153990.0727237,
        
0.07388030.07503770.07622750.07738550.07859340.0797802,
        
0.08100610.08222050.08348270.08471400.08587340.0871999,
        
0.08841370.08969480.09098200.09227970.09363500.0948243,
        
0.09612830.09747180.09882910.10009700.10143300.102847,
        
0.1042220.1054920.1068850.1083300.1096720.1110480.112438,
        
0.1138570.1153110.1167300.1181330.1195190.1209900.122452,
        
0.1239050.1254450.1268520.1283260.1297930.1312770.132817,
        
0.1343050.1357720.1372840.1388820.1403720.1419200.143445,
        
0.1449400.1465150.1481450.1496530.1511990.1528790.154368,
        
0.1559580.1576740.1592110.1607870.1624100.1640430.165693,
        
0.1672810.1689560.1705890.1722520.1738840.1755750.177208,
        
0.1788730.1805990.1822400.1839750.1856540.1873630.189106,
        
0.1907290.1925200.1941580.1958790.1976970.1993910.201164,
        
0.2028790.2046020.2064130.2081800.2099110.2117530.213484,
        
0.2152630.2170500.2188690.2206770.2223840.2242530.226071,
        
0.2278860.2297260.2315290.2333730.2352340.2370810.238853,
        
0.2407350.2426060.2444650.2463710.2482180.2501350.251944,
        
0.2538360.2557080.2575780.2595680.2614240.2633080.265313,
        
0.2671600.2690730.2710460.2729210.2748410.2768190.278735,
        
0.2806160.2826530.2846130.2865580.2884780.2904720.292474,
        
0.2944590.2963790.2983820.3003570.3023780.3043400.306853
    
);

    if (
$x >= 1.0) {
        return 
1;
    } elseif (
$x >= 0.5) {
        return 
log($x);
    }
    
$i floor($x 1000);
    if (!isset(
$savedF[$i]) || !isset($savedF[$i 1])) {
        return 
false;
    }
    return (
$savedF[$i] + (($x 1000.0) - $i) * ($savedF[$i 1] - $savedF[$i]));
}

function 
FactorProbability($exponent$B1$B2$HFF=false) {
    if (
$B1 30) {
        return 
0;
    }
    
$B2 max($B2$B1);
    if (!
$HFF) {
        
$HFF FactorBits($exponent);
    }
    
$ProbabiltyThreshold 0.001;

    
$LogK log(1.5) + (($HFF 1) * log(2)) - log($exponent);
    
$LogTemp $LogK log($B1 $B2) + log(2);

    
$FactorProbability 0;
    
$H $HFF;
    while (
true) {
        
$Prob1 DickmansFunction(log($B1) / $LogK);
        
$Aux   DickmansFunction(log($B2) / $LogTemp);

        
$Prob2 $Prob1 + (DickmansFunction(log($B2) / $LogK) - $Prob1);
        if (
$Aux != 0) {
            
$Prob2 *= DickmansFunction(log($B1) / $LogTemp) / $Aux;
        }

        
$H++;
        
$FactorProbability += $Prob2 $H;

        if (
$Prob2 $ProbabiltyThreshold) {
            break;
        }
        
$LogK    += log(2);
        
$LogTemp += log(2);
    }

    
$FudgeFactor 1.16// I don't know why, but my numbers are off by approx this much from Prime95
    
$FactorProbability *= $FudgeFactor;

    return 
$FactorProbability;
}

function 
AdminErrorEmail($file$line$subject$body) {
    
$body .= "\n\n".str_repeat('-'40)."\n";
    
$body .= '$_REQUEST:'."\n".print_r($_REQUESTtrue)."\n".str_repeat('-'40)."\n";
    
$body .= '$_GET:'    ."\n".print_r($_GET,     true)."\n".str_repeat('-'40)."\n";
    
$body .= '$_POST:'   ."\n".print_r($_POST,    true)."\n".str_repeat('-'40)."\n";
    
$body .= '$_COOKIE:' ."\n".print_r($_COOKIE,  true)."\n".str_repeat('-'40)."\n";
    
$body .= '$_SERVER:' ."\n".print_r($_SERVER,  true)."\n".str_repeat('-'40)."\n";
    
$headers  '';
    
$headers .= 'From: mersenne-aries.sili.net <'.EMAIL_JAMES.'>'."\r\n";
    
$headers .= 'Reply-To: '.EMAIL_JAMES."\r\n";
    return 
mail(EMAIL_JAMES$subject'==['.basename($file).'::'.$line."]==\n\n".$body$headers);
}

function 
SafeSQLquery($SQLquery$linenum='') {
    
$result = @mysql_query($SQLquery);
    
$error mysql_error();
    if (
$error) {
        if (@
$_SERVER['HTTP_HOST'] == 'www.example.com') {
            echo 
'<hr>'.$error.'<hr>';
        } elseif (
eregi('^Duplicate entry'$error)) {
            
// ignore
        
} else {
            
AdminErrorEmail(__FILE____LINE__'Mersenne-Aires SQL error'$error."\n\n".'On line '.$linenum."\n".'While processing query:'."\n".$SQLquery);
        }
    }
    return 
$result;
}

function 
getUserCompID($usernamestring$compidstring) {
    static 
$UserCompIDlookup = array();
    if (!isset(
$UserCompIDlookup[$usernamestring][$compidstring])) {
        
$SQLquery  'SELECT `usercompid`';
        
$SQLquery .= ' FROM `usercomp`';
        
$SQLquery .= ' WHERE (`userid` = "'.mysql_escape_string($usernamestring).'")';
        
$SQLquery .= ' AND (`compid` = "'.mysql_escape_string($compidstring).'")';
        
$result mysql_query($SQLquery);
        if (
$row mysql_fetch_assoc($result)) {
            
$UserCompIDlookup[$usernamestring][$compidstring] = $row['usercompid'];
        } else {
            
$SQLquery  'INSERT INTO `usercomp` (`userid`, `compid`) VALUES (';
            
$SQLquery .= '"'.mysql_escape_string($usernamestring).'", ';
            
$SQLquery .= '"'.mysql_escape_string($compidstring).'")';
            
mysql_query($SQLquery);
            
$UserCompIDlookup[$usernamestring][$compidstring] = mysql_insert_id();
        }
    }
    if (!
$UserCompIDlookup[$usernamestring][$compidstring]) {
        
AdminErrorEmail(__FILE____LINE__'Mersenne-aries: failed to getUserCompID('.$usernamestring.', '.$compidstring.')'$SQLquery."\n\n".mysql_error());
        echo 
'An error has occurred, sorry. The site administrator has been notified and will fix it shortly.';
        exit;
    }
    return 
$UserCompIDlookup[$usernamestring][$compidstring];
}

function 
getCompName($usercompid) {
    static 
$CompNameLookup = array();
    if (!isset(
$CompNameLookup[$usercompid])) {
        
$CompNameLookup[$usercompid] = '';

        
$SQLquery  'SELECT `compid`';
        
$SQLquery .= ' FROM `usercomp`';
        
$SQLquery .= ' WHERE (`usercompid` = "'.mysql_escape_string($usercompid).'")';
        
$result mysql_query($SQLquery);
        if (
$row mysql_fetch_assoc($result)) {
            
$CompNameLookup[$usercompid] = $row['compid'];
        }
    }
    return 
$CompNameLookup[$usercompid];
}

function 
EmailAttachment($from$to$subject$textbody, &$attachmentdata$attachmentfilename$base64encode=true) {
    
$boundary '_NextPart_'.time().'_'.md5($attachmentdata).'_';

    
$textheaders  '--'.$boundary."\n";
    
$textheaders .= 'Content-Type: text/plain; format=flowed; charset="iso-8859-1"'."\n";
    
$textheaders .= 'Content-Transfer-Encoding: 7bit'."\n\n";

    
$attachmentheaders  '--'.$boundary."\n";
    if (
$base64encode) {
        
$attachmentheaders .= 'Content-Type: application/octet-stream; name="'.$attachmentfilename.'"'."\n";
        
$attachmentheaders .= 'Content-Transfer-Encoding: base64'."\n";
    } else {
        
$attachmentheaders .= 'Content-Type: text/plain; name="'.$attachmentfilename.'"'."\n";
        
$attachmentheaders .= 'Content-Transfer-Encoding: 7bit'."\n";
    }
    
$attachmentheaders .= 'Content-Disposition: attachment; filename="'.$attachmentfilename.'"'."\n\n";


    
$headers[] = 'From: '.$from;
    
$headers[] = 'Content-Type: multipart/mixed; boundary="'.$boundary.'"';

    return @
mail($to$subject$textheaders.ereg_replace("[\x80-\xFF]"'?'$textbody)."\n\n".$attachmentheaders.($base64encode wordwrap(base64_encode($attachmentdata), 76"\n"true) : $attachmentdata)."\n\n".'--'.$boundary."--\n\n"implode("\r\n"$headers));
}

function 
caseinsensitivesortsub($a$b) {
    
$a strtolower($a);
    
$b strtolower($b);
    if (
$a == $b) {
       return 
0;
    } elseif (
$a $b) {
        return 
1;
    }
    return -
1;
}

function 
BarGraph($width$height=10$color='0033CC'$title='') {
    return 
'<img src="index.php?px='.$color.'" height="'.max(1round($height)).'" width="'.max(1round($width)).'" border="0" title="'.htmlentities($title).'">';
}

function 
GetPct($numerator$denominator) {
    if (
$denominator == 0) {
        return 
0;
    }
    return ((
$numerator $denominator) * 100);
}

function 
NonZeroMin() {
    
$arg_list func_get_args();
    
$NonZeroValues = array();
    if ((
func_num_args() == 1) && is_array($arg_list[0])) {
        
$values_to_check $arg_list[0];
    } else {
        
$values_to_check $arg_list;
    }
    foreach (
$values_to_check as $key => $value) {
        if (
$value) {
            
$NonZeroValues[] = $value;
        }
    }
    if (
count($NonZeroValues) == 0) {
        return 
false;
    }
    return 
min($NonZeroValues);
}

function 
Range2bgcolor($value$maxvalue$emptyvalue=null) {
    if ((
strlen($value) == 0) && !is_null($emptyvalue)) {
        return 
$emptyvalue;
    }
    
$value min(max(0$value), $maxvalue);
    
$scale round(($value $maxvalue) * 255);
    
$r str_pad(dechex(                                      $scale), 2'0'STR_PAD_LEFT);
    
$g str_pad(dechex(                                255 $scale), 2'0'STR_PAD_LEFT);
    
$b str_pad(dechex(round(255 * (abs((128 $scale) / 128)))), 2'0'STR_PAD_LEFT);
    return 
$r.$g.$b;
}

function 
NiceTimeFormatting($seconds$precision=1$returnparts=false) {
    
$sign = (($seconds 0) ? -1);
    
$seconds abs($seconds);
    do {
        if (
$seconds 100) {
            
$value number_format($seconds0);
            
$unit  'second'.(($seconds 1) ? 's' '');
            break;
        }
        
$minutes $seconds 60;
        if (
$minutes 60) {
            
$value number_format($minutes$precision);
            
$unit  'minutes';
            break;
        }
        
$hours $seconds 3600;
        if (
$hours 24) {
            
$value number_format($hours$precision);
            
$unit  'hours';
            break;
        }
        
$days $seconds 86400;
        if (
$days 60) {
            
$value number_format($days$precision);
            
$unit  'days';
            break;
        }
        
$months $seconds / (30 86400);
        if (
$months 12) {
            
$value number_format($months$precision);
            
$unit  'months';
            break;
        }
        
$years $seconds / (365 86400);
        if (
true) {
            
$value number_format($years$precision);
            
$unit  'years';
            break;
        }
    } while (
false);
    
$value *= $sign;
    if (
$returnparts) {
        return array(
$value$unit);
    }
    return 
$value.' '.$unit;
}

?>
cpucredit.inc.php:
<?php
//$MODULE_NAME_ = $app_name . '/' . $api_version . '_cpu_credit.inc.php';
//if ( $DEBUG_FLAG ) print "DEBUG: MODULE $MODULE_NAME_ ($function_module) reporting<br>";

function fft_lookup_table() {
    static 
$fft_lookup_table = array();
    if (empty(
$fft_lookup_table)) {
        
//$fft_lookup_table[FFTSIZE] = array(TIMING, MIN_EXPONENT, MAX_EXPONENT);
        
$fft_lookup_table[32]       = array(8.7840E-7,         0,       743);
        
$fft_lookup_table[48]       = array(1.1400E-6,       743,      1099);
        
$fft_lookup_table[64]       = array(1.4088E-6,      1099,      1469);
        
$fft_lookup_table[80]       = array(1.7592E-6,      1469,      1827);
        
$fft_lookup_table[96]       = array(2.0520E-6,      1827,      2179);
        
$fft_lookup_table[112]      = array(2.4624E-6,      2179,      2539);
        
$fft_lookup_table[128]      = array(2.5272E-6,      2539,      2905);
        
$fft_lookup_table[160]      = array(3.5640E-6,      2905,      3613);
        
$fft_lookup_table[192]      = array(4.2936E-6,      3613,      4311);
        
$fft_lookup_table[224]      = array(5.2512E-6,      4311,      5029);
        
$fft_lookup_table[256]      = array(5.4744E-6,      5029,      5755);
        
$fft_lookup_table[320]      = array(7.3440E-6,      5755,      7149);
        
$fft_lookup_table[384]      = array(8.7840E-6,      7149,      8527);
        
$fft_lookup_table[448]      = array(1.0536E-5,      8527,      9933);
        
$fft_lookup_table[512]      = array(1.1328E-5,      9933,     11359);
        
$fft_lookup_table[640]      = array(1.7040E-5,     11359,     14119);
        
$fft_lookup_table[768]      = array(2.0592E-5,     14119,     16839);
        
$fft_lookup_table[896]      = array(2.5416E-5,     16839,     19639);
        
$fft_lookup_table[1024]     = array(2.7648E-5,     19639,     22477);
        
$fft_lookup_table[1280]     = array(3.9120E-5,     22477,     27899);
        
$fft_lookup_table[1536]     = array(4.7592E-5,     27899,     33289);
        
$fft_lookup_table[1792]     = array(5.6880E-5,     33289,     38799);
        
$fft_lookup_table[2048]     = array(6.1680E-5,     38799,     44339);
        
$fft_lookup_table[2560]     = array(8.5200E-5,     44339,     55099);
        
$fft_lookup_table[3072]     = array(1.0248E-4,     55099,     65729);
        
$fft_lookup_table[3584]     = array(1.2648E-4,     65729,     76559);
        
$fft_lookup_table[4096]     = array(1.2960E-4,     76559,     87549);
        
$fft_lookup_table[5120]     = array(1.9200E-4,     87549,    108800);
        
$fft_lookup_table[6144]     = array(2.2560E-4,    108800,    129900);
        
$fft_lookup_table[7168]     = array(2.7600E-4,    129900,    151300);
        
$fft_lookup_table[8192]     = array(2.8560E-4,    151300,    172700);
        
$fft_lookup_table[10240]    = array(3.9840E-4,    172700,    214400);
        
$fft_lookup_table[12288]    = array(4.8480E-4,    214400,    255300);
        
$fft_lookup_table[14336]    = array(5.9040E-4,    255300,    297300);
        
$fft_lookup_table[16384]    = array(6.1440E-4,    297300,    340400);
        
$fft_lookup_table[20480]    = array(8.3760E-4,    340400,    423300);
        
$fft_lookup_table[24576]    = array(1.0176E-3,    423300,    504600);
        
$fft_lookup_table[28672]    = array(1.2600E-3,    504600,    587500);
        
$fft_lookup_table[32768]    = array(1.3128E-3,    587500,    671400);
        
$fft_lookup_table[40960]    = array(1.7256E-3,    671400,    835200);
        
$fft_lookup_table[49152]    = array(2.0952E-3,    835200,    995500);
        
$fft_lookup_table[57344]    = array(2.5608E-3,    995500,   1158000);
        
$fft_lookup_table[65536]    = array(2.7384E-3,   1158000,   1325000);
        
$fft_lookup_table[81920]    = array(3.8592E-3,   1325000,   1648000);
        
$fft_lookup_table[98304]    = array(4.6872E-3,   1648000,   1966000);
        
$fft_lookup_table[114688]   = array(5.6808E-3,   1966000,   2287000);
        
$fft_lookup_table[131072]   = array(5.9928E-3,   2287000,   2614000);
        
$fft_lookup_table[163840]   = array(7.3536E-3,   2614000,   3251000);
        
$fft_lookup_table[196608]   = array(9.0744E-3,   3251000,   3875000);
        
$fft_lookup_table[229376]   = array(1.0776E-2,   3875000,   4512000);
        
$fft_lookup_table[262144]   = array(1.1976E-2,   4512000,   5158000);
        
$fft_lookup_table[327680]   = array(1.5312E-2,   5158000,   6421000);
        
$fft_lookup_table[393216]   = array(1.8840E-2,   6421000,   7651000);
        
$fft_lookup_table[458752]   = array(2.2560E-2,   7651000,   8908000);
        
$fft_lookup_table[524288]   = array(2.5200E-2,   8908000,  10180000);
        
$fft_lookup_table[655360]   = array(3.3264E-2,  10180000,  12650000);
        
$fft_lookup_table[786432]   = array(4.1376E-2,  12650000,  15070000);
        
$fft_lookup_table[917504]   = array(4.9200E-2,  15070000,  17550000);
        
$fft_lookup_table[1048576]  = array(5.5920E-2,  17550000,  20050000);
        
$fft_lookup_table[1310720]  = array(7.0080E-2,  20050000,  24930000);
        
$fft_lookup_table[1572864]  = array(8.5920E-2,  24930000,  29690000);
        
$fft_lookup_table[1835008]  = array(1.0224E-1,  29690000,  34560000);
        
$fft_lookup_table[2097152]  = array(1.1376E-1,  34560000,  39500000);
        
$fft_lookup_table[2621440]  = array(1.5000E-1,  39500000,  49100000);
        
$fft_lookup_table[3145728]  = array(1.8312E-1,  49100000,  58520000);
        
$fft_lookup_table[3670016]  = array(2.1840E-1,  58520000,  68130000);
        
$fft_lookup_table[4194304]  = array(2.4360E-1,  68130000,  77910000);
        
$fft_lookup_table[5242880]  = array(3.1296E-1,  77910000,  96830000);
        
$fft_lookup_table[6291456]  = array(3.7920E-1,  96830000115300000);
        
$fft_lookup_table[7340032]  = array(4.5840E-1115300000134200000);
        
$fft_lookup_table[8388608]  = array(5.0400E-1134200000153400000);
        
$fft_lookup_table[10485760] = array(6.7200E-1153400000190700000);
        
$fft_lookup_table[12582912] = array(8.1120E-1190700000227300000);
        
$fft_lookup_table[14680064] = array(9.8400E-1227300000264600000);
        
$fft_lookup_table[16777216] = array(1.0800E-0264600000302600000);
        
$fft_lookup_table[20971520] = array(1.4904E-0302600000376100000);
        
$fft_lookup_table[25165824] = array(1.8216E-0376100000448000000);
        
$fft_lookup_table[29360128] = array(2.1792E-0448000000521500000);
        
$fft_lookup_table[33554432] = array(2.3832E-0521500000596000000);
    }
    return 
$fft_lookup_table;
}

function 
fft_timings_lookup($exponent=0$fftlen=0) {
    static 
$fft_lookup_table = array();
    if (empty(
$fft_lookup_table)) {
        
$fft_lookup_table fft_lookup_table();
    }
    if ((
$fftlen 0) && isset($fft_lookup_table[$fftlen])) {
        return 
$fft_lookup_table[$fftlen][0];
    }
    if (
$exponent) {
        foreach (
$fft_lookup_table as $fftLength => $dataarray) {
            if ((
$exponent >= $dataarray[1]) && ($exponent <= $dataarray[2])) {
                if (
$fftlen == -1) {
                    return 
$fftLength;
                } else {
                    return 
$dataarray[0];
                }
            }
        }
    }
    return 
null;
}

// CPU credit - background information:
//
// In Primenet v4 we used a 90 MHz Pentium CPU as the benchmark machine
// for calculating CPU credit.  The official unit of measure became the
// P-90 CPU year.  In 2007, not many people own a plain Pentium CPU, so we
// adopted a new benchmark machine - a single core of a 2.4 GHz Core 2 Duo.
// Our official unit of measure became the C2GHD (Core 2 GHz Day).  That is,
// the amount of work produced by the single core of a hypothetical
// 1 GHz Core 2 Duo machine.  A 2.4 GHz should be able to produce 4.8 C2GHD
// per day.
//
// To compare P-90 CPU years to C2GHDs, we need to factor in both the
// the raw speed improvements of modern chips and the architectural
// improvements of modern chips.  Examining prime95 version 24.14 benchmarks
// for 640K to 2048K FFTs from a P100, PII-400, P4-2000, and a C2D-2400
// and compensating for speed differences, we get the following architectural
// multipliers:
//
// One core of a C2D = 1.68 P4.
// A P4 = 3.44 PIIs
// A PII = 1.12 Pentium
//
// Thus, a P-90 CPU year = 365 days * 1 C2GHD *
//               (90MHz / 1000MHz) / 1.68 / 3.44 / 1.12
//             = 5.075 C2GHDs


// v4 conversion
function credit_v4_C2D_CPU_GhzDays$v4_P90_years )
{
    
// A P-90 CPU year = 5.075 C2D_GHzDays
    
return ( 5.075 $v4_P90_years );
}


/* Return the timing (in seconds) for a single core of a hypothetical
   1GHz Core 2 Duo to perform one LL iteration (a single squaring).
We need to look up timing in two ways.
1) Given an fftlen - return the timing.
2) Given an exponent, finds the likely fftlen
using min_exp and max_exp and return the timing.
We need two lookups because users that manually
reported results will not know the fftlen.
Prime95 should always pass in the fft length.
*/
function credit_get_FFT_timing$exponent$fftlen )
{
    
// $exponent is REQUIRED, $fftlen is PREFERRED
    // returns NULL or float of timing found

    
return fft_timings_lookup($exponent$fftlen);

//    // try FFT length first
//    if ( $fftlen ) {
//        $t_timing = sql_select_rows_array_where('t_gimps_credit_timings', "fftlen = $fftlen" );
//    }
//    // else match by exponent range
//    if ( !$t_timing )
//        $t_timing = sql_select_rows_array_where(
//                't_gimps_credit_timings',
//                "$exponent >= min_exponent and $exponent <= max_exponent" );
//    return $t_timing[timing];
}

// An LL test (prime or composite)
// timing / 86400 * exponent
function credit_cpu_LL$exponent$fftlen )
{
    
$timing credit_get_FFT_timing$exponent$fftlen );
    return ( 
$timing $exponent 86400.0 );
}

// ECM (whether factor found or not)
// timing / 86400 * curves * (13.0 * B1 + 0.06 * B2)
// Note: the user gets a slight cpu bonus when factor found in stage 1
function credit_cpu_ECM$exponent$fftlen$curves_run$B1$B2 )
{
    
$timing credit_get_FFT_timing$exponent$fftlen );
    return ( 
$timing $curves_run * ( 13.0 $B1 0.06 $B2) / 86400.0 );
}

// P-1 - no factor
// timing / 86400 * (1.5 * B1 + 0.05 * B2)
// P-1 - factor found in stage 2
// timing / 86400 * (1.5 * B1 + 0.05 * B2)
// P-1 - factor found in stage 1, B2 = 0
// timing / 86400 * (1.5 * B1)
function credit_cpu_PM1_factoring$exponent$fftlen$B1$B2 )
{
    
$timing credit_get_FFT_timing$exponent$fftlen );

    
// revised formula posted by George 26-Jan-2009:
    // http://mersenneforum.org/showthread.php?t=11411
    // > P-1 was being under-credited. The new formula is:
    // > GHz_days = timing * ( 1.45 * B1 + 0.079 * (B2 - B1) ) / 86400.0
    // DEPRECATED (as of 26-Jan-2009): return ( $timing * ( 1.5 * $B1 + 0.05 * $B2) / 86400.0 );
    
if ($B1 >= $B2) {
        return ( 
$timing * ( 1.45 $B1 ) / 86400.0 );
    } else {
        return ( 
$timing * ( 1.45 $B1 0.079 * ($B2 $B1) ) / 86400.0 );
    }
}


// Trial factoring needs a different timing table
// (or else hardwire the timings in PHP code):
//bits    tf_timing
//----    ---------
//<=62    0.00465
//63-64    0.00743
//>=65    0.00707
function credit_get_TF_timing$bits )
{
    
// will later move to table maybe so we don't maintain in code
    
if ( $bits <= 62 ) return (2.4*0.00465);
    elseif ( 
$bits == 63 || $bits == 64 ) return (2.4*0.00743);
    elseif ( 
$bits >= 65 ) return (2.4*0.00707);
}

// Trial factoring - no factor found:
function credit_cpu_TF_no_factor$exponent$sf$ef )
{
    
// modifications by james@jamesheinrich.com 2008-12-13
    
$est 0.0;
    if (
$exponent && $ef) {
        for ( 
$i $sf+1$i <= $ef$i++ ) {
            
//if ($i < 48) continue; // marginally faster calculations if this is present, but will return zero for small factors <2^48 factoring, instead of <smallvalue>
            
$tf_timing credit_get_TF_timing$i );
            
//$est += $tf_timing * (1 << ($i - 48)) * 1680.0 / $exponent; // broken above $i=78 due to 32bit-signed integers
            
$est += $tf_timing pow(2, ($i 48)) * 1680.0 $exponent;
        }
    }
    return 
$est;
}


function 
credit_factor_mod_120$factor )
{
    
// $factor must be a string of decimal digits
    // Chinese Remainder Theorem mod 120:
    // m = 3, n = 40, u = -13, v = 1
    // a = factor mod 3, b = factor mod 40
    // m120 = factor mod 120
    
$a 0;
    
$L strlen($factor);
    for ( 
$i 0$i $L$i++ ) {
        
$d ord($factor{$i}) - ord('0');
        if ( 
$d || $d ) return -1;    // digit check
        
$a += $d;
    }
    
$a %= 3// sum of digits, mod 3
    
$b substr($factor,$L-3,3) % 40;    // right 3 digits, mod 40
    
$m120 40*$a 39*$b;    // mod 120
    
while ( $m120 $m120 += 120;
    return ( 
$m120 );
}

// approximate log2( decimal digits string )
function credit_log2_factor$factor )
{
    
// $factor must be a string of decimal digits
    
$L strlen($factor);
    if (
$L 6) {
        
$msd substr($factor06);
        
$i log($msd2) + 3.322 * ($L 6);
    } else {
        
$i log($factor2);
    }
    return 
$i;
}

//// get sf value from t_gimps_factoring_effort table
//function credit_get_sf_from_exponent( $exponent )
//{
//    $t_fe = sql_select_rows_array_where( 't_gimps_factoring_effort', "exponent = $exponent" );
//    return ( $t_fe[no_factor_to_bits] );
//}

// Trial factoring - factor found by prime95
// pass = lookup (factor mod 120) in
//         {1,7,17,23,31,41,47,49,71,73,79,89,97,103,113,119}
//    (pass is now integer between 0 and 15)
// i = log2 (factor)
// ef = sf+1;
// assume we did (pass + (i - sf)) / 16 * credit-for-tfing-from-sf-to-ef.

function credit_cpu_TF_factor_p95$exponent$factor$sf )
{
    
$fact_mod_120 credit_factor_mod_120($factor);
    
$passes = array(171723314147497173798997103113119);
    for (
$pass 0$pass count($passes); $pass++) {
        if (
$passes[$pass] == $fact_mod_120) {
            break;
        }
    }
    if (
$pass == count($passes)) {
        return 
0.0;
    }

    
$i credit_log2_factor($factor);
    
$floor_i floor($i);
    
$ef $floor_i 1;

    return ( 
credit_cpu_TF_no_factor$exponent$sf$floor_i ) + ($pass + ($i $floor_i)) / 16.0 credit_cpu_TF_no_factor$exponent$floor_i$ef ) );
}


// Trial factoring - factor found by other client
// Caller must get $sf from t_gimps_factoring_effort prior to calling the
// record_common_factor_routine.  This is because recording the factor will
// delete the t_gimps_factoring_effort row.
// i = log2 (factor)
// sf = trunc (i);
// ef = sf+1;
// assume we did (i - sf) * credit-for-tfing-from-sf-to-ef.

function credit_cpu_TF_factor_other$exponent$factor$sf )
{
    
$i credit_log2_factor$factor );
    
$floor_i floor$i );
    
$ef $floor_i 1;
    return ( 
credit_cpu_TF_no_factor$exponent$sf$floor_i ) +
         (
$i $floor_i) * credit_cpu_TF_no_factor$exponent$floor_i$ef ) );
}

?>