PHP Function – Infinity Multiplication – Beyond Memory

Advertisement

<?php
// "Copyright Notice", please do not remove.
// Written by Kevin Ng
// The full tutorial on this subject can be found @ http://kevinhng86.iblog.website or http://programming.world.edu.
// Release date to http://programming.world.edu will lag at least one week after release on http://kevinhng86.iblog.website 
// This source code file is a part of Kevin Ng's Z library.
// This source code is licenses under CCDL-1.0  A copy of CDDL1.0 can be found at https://opensource.org/licenses/CDDL-1.0
// End "Copyright Notice" 

// Notice: This is the protype version of infiXF.   
//         This version does support decimal calculation.
//         InfiXF is for sciencetific use.

// Limitation: Although had not calculate the number to be that large yet, in theory InfiXF can calculate two strings of digits that are 1/5 the size of the hard drive.
//             If the hard drive is 1 Terabyte, This program can calculate the multiplication procedure for two strings of digit with the combine storage of 200 GB.
//             That is about 100 billion digits in length for each string of digits.
//             This version does not come with the renderer.
//             After a huge calculation, and if the answer file is larger than 1GB another program woulb be requires to render the answer on screen.
//             InfiXF does not consume memory and have very little memory foot print.
//             InfiXF however does requires the storage space as large as the two files that contained the strings of digits to produce the answer string.
// Notice : This program depend greatly on the filesize() function of PHP. 
//          To actually calculate up to hard-drive storage with the prototype of infiXF, the filesize() function must return a signed long integer and not a signed integer.
//          There is a method to work around the limitation, but the method won't be implement until the final release of XF.
//          Without the signed long integer return from the filesize() function, this program can only calculate up to nine digits less than one billion digits multiply by nine digits less than one billion digits.
    
function infiXF(){
    $afile = "a.infiX"; 
    $bfile = "b.infiX";
    $atmp = $afile . ".tmp";
    $btmp = $bfile . ".tmp";
    $outputfile = "result.infiX";
    $outputtmp = $outputfile . ".tmp";
    $dAfterDecA = -1;
    $dAfterDecB = -1;
    $dAfterDecT = 0;
        
    $perReadTmp = 50; # This is changeable, how many character to read at once during temporary file reading.
    clearstatcache();
    $asize = filesize($afile) or die("File $afile does not exist or is empty \n"); 
    $bsize = filesize($bfile) or die("File $bfile does not exist or is empty \n");
    $tmpDReadA = 0;
    $tmpDReadB = 0;
    $readA = "";
    $readB = "";
   
    $FileA = fopen($afile, "r") or die;
        $readA = fread($FileA, 1);
        $isaNeg = $readA == "-";
            
        $TmpA = fopen($atmp, "w") or die;
            fseek($FileA, 0 ,0);
            $readA = fread($FileA, $perReadTmp);
            $readA = ltrim($readA, "+-");
            $readA = rtrim($readA);                        
            $dAfterDecA = strpos($readA, ".");
            $dAfterDecA = $dAfterDecA !== false? (strlen($readA) - 1 - $dAfterDecA) : -1; 
             if ($dAfterDecA > -1){
            $readA = str_replace(".", "", $readA);
            }                        
            fwrite($TmpA, $readA);
                
            while (!(feof($FileA))){
                $readA = fread($FileA, $perReadTmp);
                $readA = rtrim($readA);                        
                if ($dAfterDecA < 0){
                    $dAfterDecA = strpos($readA, ".");
                    $dAfterDecA = $dAfterDecA !== false? (strlen($readA) - 1 - $dAfterDecA) : -1; 
                    if ($dAfterDecA > -1){
                        $readA = str_replace(".", "", $readA);
                    }
                } else {
                    $tmpDReadA = strlen($readA);
                    $dAfterDecA = $dAfterDecA + $tmpDReadA;    
                }
                fwrite($TmpA, $readA);
            }    
        fclose($TmpA);
    fclose ($FileA);
    
    $FileB = fopen($bfile, "r") or die;
        $readB = fread($FileB, 1);
        $isbNeg = $readB == "-";
            
        $TmpB = fopen($btmp, "w") or die;
            fseek($FileB, 0 ,0);
            $readB = fread($FileB, $perReadTmp);
            $readB = ltrim($readB, "+-");
            $readB = rtrim($readB);                        
            $dAfterDecB = strpos($readB, ".");
            $dAfterDecB = $dAfterDecB !== false ? (strlen($readB) - 1 - $dAfterDecB) : -1; 
             if ($dAfterDecB > -1){
                $readB = str_replace(".", "", $readB);
            }                        
            fwrite($TmpB, $readB);
                
            while (!(feof($FileB))){
                $readB = fread($FileB, $perReadTmp);
                $readB = rtrim($readB);                        
                if ($dAfterDecB < 0){
                    $dAfterDecB = strpos($readB, ".");
                    $dAfterDecB = $dAfterDecB !== false? (strlen($readB) - 1 - $dAfterDecB) : -1; 
                    if ($dAfterDecB > -1){
                        $readB = str_replace(".", "", $readB);
                    }
                } else {
                    $tmpDReadB = strlen($readB);
                    $dAfterDecB = $dAfterDecB + $tmpDReadB;    
                }
                fwrite($TmpB, $readB);
            }    
        fclose($TmpB);
    fclose ($FileB);


    $dAfterDecA = $dAfterDecA < 0? 0 : $dAfterDecA;
    $dAfterDecB = $dAfterDecB < 0? 0 : $dAfterDecB;
    $dAfterDecT = $dAfterDecA + $dAfterDecB;
    clearstatcache();
    $atmpsize = filesize($atmp);
    $btmpsize = filesize($btmp);
    $digit = 9; # This is the amount of digits to calculate per cycle.
    $digitneg = $digit * -1;
    $pad0 = "";
    while (strlen($pad0) < ($digit - 1)){
        $pad0 = "0" . $pad0;
    }

    $OutputTmp = fopen($outputtmp,"w") or die;
        $idn = 0;
        $premakeoutlen = ($atmpsize + $btmpsize) + ($digit * 2) ;
        while ($idn < $premakeoutlen ){
            fwrite($OutputTmp, (strlen($pad0) > 0? $pad0 : "0"));
            $idn = $idn + (($digit - 1 == 0)? 1 : $digit - 1) ;
        }    
    fclose($OutputTmp);


    $a = 0;
    $b = 0;
    $o = 0;
    $posrB = 1;
    $posrO = 1;
    $loopidxB = 1;
    $temp = 0;
    $tempadd = 0;
    $blen = $btmpsize;
    clearstatcache();
    $olen = filesize($outputtmp);

    $TmpB    = fopen($btmp, "r") or die;
        while ( $posrB != 0 ){
            $alen = $atmpsize;
            $posrA = 1;
            $leftover = 0;
            $remainder = 0;
            $loopidxA = 1;
            $posrB = $blen - ($loopidxB * $digit);
            
            fseek($TmpB, ($posrB > 0 ? $posrB : 0) ,0);    
            $b = fread($TmpB, ($posrB > 0 ? $digit : $digit + $posrB));

            $TmpA = fopen($atmp, "r") or die;
                $OutputTmp = fopen($outputtmp, "c+") or die;
                    while ( $posrA > 0 ){
                            $posrO = $olen - (($loopidxA + $loopidxB - 1) * $digit);
                            $posrA = $alen - ($loopidxA * $digit);
                            fseek($TmpA, ($posrA > 0 ? $posrA : 0),0);    
                            $a = fread($TmpA, ($posrA > 0? $digit : $digit + $posrA));        
                            $temp = intval($b) * intval($a) + $remainder + $leftover;
                            $leftover = intval(substr(strval($temp),0, $digitneg)) ;
                            fseek($OutputTmp, $posrO, 0);
                            $o = fread($OutputTmp, $digit);
                            $tempadd = intval(substr(strval($temp),$digitneg)) + intval($o) ;
                            $remainder = intval(substr(strval($tempadd),0, $digitneg));
                            fseek($OutputTmp, $posrO, 0);
                            fwrite($OutputTmp, substr($pad0 . substr(strval($tempadd),$digitneg), $digitneg));                
                            $posrA = $posrA > 0 ? $posrA : 0;
                            $loopidxA = $loopidxA + 1;    
                    }
                    if ( $remainder + $leftover > 0 ){
                        $posrO = $posrO - $digit;
                        fseek($OutputTmp, $posrO, 0);
                        fwrite($OutputTmp, substr($pad0 . strval($remainder + $leftover), $digitneg));
                    }
                fclose($OutputTmp);
            fclose($TmpA);

            $posrB = $posrB > 0? $posrB : 0;
            $loopidxB = $loopidxB + 1;
        }
    fclose($TmpB);

    $dBeforeDec = $olen - $dAfterDecT; 
    $lead0End = 0;
    $posw = 0;
    $readOutputTmp = "";
    $checker = "";
    $truncatediff = 0;
    $truncatelen = 0;
    $truncatestr = "";
 

    $OutputTmp = fopen($outputtmp , "r");
        $Output = fopen($outputfile, "w");
            if ( $isaNeg != $isbNeg ){
                fwrite($Output, "-");
            }
    
            while ($posw < $dBeforeDec ){
                fseek($OutputTmp, $posw, 0);
                $readOutputTmp = fread($OutputTmp, (($posw + $perReadTmp < $dBeforeDec)? $perReadTmp : $dBeforeDec - $posw));
                if ( $lead0End == 0 ){
                       $readOutputTmp = ltrim($readOutputTmp, "0");
                    $lead0End = strlen($readOutputTmp) > 0? 1 : 0; 
                }
                fwrite($Output, $readOutputTmp);
                $posw = ($posw + $perReadTmp < $dBeforeDec)? $posw + $perReadTmp : $dBeforeDec  ;
            }
        fclose($Output);

        clearstatcache();
        $outputlen = filesize($outputfile);

        $Output = fopen($outputfile, "a+" );    
            if ($outputlen < 2){
                $checker = fread($Output, 2);
                if ( strlen($checker) < 1 || $checker == "-"){
                    fwrite($Output, "0");
                }                
            } 
                
            if ( $dAfterDecT > 0 ){
                fwrite($Output, ".");
            }            
        
            while ( $posw < $olen ){
                fseek($OutputTmp, $posw, 0);
                $readOutputTmp = fread($OutputTmp, $perReadTmp);
                $truncatestr = $readOutputTmp;
                $truncatestr = rtrim($readOutputTmp,"0");
                $truncatediff = strlen($readOutputTmp) - strlen($truncatestr);
                $truncatelen =  $truncatediff == strlen($readOutputTmp)? $truncatediff + $truncatelen : $truncatediff;        
                fwrite($Output, $readOutputTmp);                
                $posw = $posw + $perReadTmp;
            }
        fclose($Output);
    fclose($OutputTmp);  
    
    clearstatcache();
    $outputlen = filesize($outputfile);
        
    $Output = fopen ($outputfile, "a" );    
        ftruncate($Output,  ($outputlen - $truncatelen));
    fclose($Output);
        
    clearstatcache();
    $outputlen = filesize($outputfile);

    $Output = fopen ($outputfile, "a+");    
        fseek($Output, $outputlen - 1, 0);
        $readOutputTmp = fread($Output, 1 );
        if ( $readOutputTmp == "."){
            ftruncate($Output, $outputlen - 1);
        }
    fclose($Output);
}


function fileRand(){
    $randDigitA = intval(rand(0,350)) + 40;
    $randDigitB = intval(rand(0,350)) + 40;

    $randDecPOSA = intval(rand(0,$randDigitA - 20)) + 10; 
    $randDecPOSB = intval(rand(0,$randDigitB - 20)) + 10;

    $RANDOMA = fopen("a.infiX", "w") or die("Could not open file $!");
       fwrite($RANDOMA, "-");
       for ($id = 0; $id < $randDigitA; $id++){
           fwrite($RANDOMA, intval(rand(0,9)));
           if ($id == $randDecPOSA){
                fwrite($RANDOMA, ".");                
           }    
       }
    fclose($RANDOMA);

    $RANDOMB = fopen("b.infiX", "w") or die ("Could not open file $!");        
        for ($id = 0; $id < $randDigitB; $id++){
            fwrite($RANDOMB, intval(rand(0,9)));
             if ($id == $randDecPOSB){
                fwrite($RANDOMB, ".");    
            }    
        }
    fclose($RANDOMB);
}

fileRand();
infiXF();
print "Check in the current directory.\n a.infiX is the file that hold the first set of digits.\n b.infiX is the second file that hold the digits.\n result.infiX is the result of the multiplication procedure.\n";
print "The name of the temporary file for them are a.infiX.tmp, b.infiX.tmp, result.infiX.tmp.\n";
print "Temporary files can be delete after execution, but are currently kept for debuging purposes.";


?>
Advertisement
directory-software-online-bussiness-script


Random Article You May Like