Java Function – Infinity Multiplication – Beyond Memory

Advertisement

/* "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.
 */          

import java.io.File;
import java.io.FileWriter;
import java.io.RandomAccessFile;
import java.io.IOException;

public class libZ
{
    public static void main(String[] args)
    {
        randFile();
        infiXF();
        System.out.println("Check in the current directory.");
        System.out.println(" a.infiX is the file that hold the first set of digits.");
        System.out.println(" b.infiX is the second file that hold the digits.");
        System.out.println(" result.infiX is the result of the multiplication procedure.");
        System.out.println("The name of the temporary file for them are a.infiX.tmp, b.infiX.tmp, result.infiX.tmp.");
        System.out.println("Temporary files can be delete after execution, but are currently kept for debuging purposes.");
        System.exit(0);
    }
    
    public static void randFile() 
    { 
        String fileA = "a.infiX";
        String fileB = "b.infiX";
        int randDigitA = (int)(Math.random() * (350 - 0) + 40);
        int randDigitB = (int)(Math.random() * (350 - 0) + 40);
        int randDecPOSA = (int)(Math.random() * (randDigitA - 20) + 20);
        int randDecPOSB = (int)(Math.random() * (randDigitB - 20) + 20);

        try {
            FileWriter RANDOMA;
                RANDOMA = new FileWriter(fileA);
                RANDOMA.write("-");
                for (int idn = 0; idn < randDigitA; idn++){
                    RANDOMA.write(""+(int)(Math.random() * (9 - 0) + 0));
                    if (idn == randDecPOSA){
                        RANDOMA.write(".");
                    }
                }
            RANDOMA.close();
              
            FileWriter RANDOMB = new FileWriter(fileB);
                for (int idn = 0; idn < randDigitB; idn++){
                    RANDOMB.write(""+(int)(Math.random() * (9 - 0) + 0));
                    if (idn == randDecPOSB){
                        RANDOMB.write(".");
                    }
                }
            RANDOMB.close();
            
        } catch (IOException e) {
            throw new IllegalArgumentException("Unable to create " + fileA + " and " + fileB , e);
        }
           
    }
    
    public static void infiXF() 
    { 
        boolean isaNeg;
        boolean isbNeg;
        String afile = "a.infiX";
        String bfile = "b.infiX";
        String atmp = afile.concat(".tmp");
        String btmp = bfile.concat(".tmp");
        String outputfile = "result.infiX";
        String outputtmp = outputfile.concat(".tmp");
        String readA = "";
        String readB = "";
        long dAfterDecA = -1;
        long dAfterDecB = -1;
        long dAfterDecT = 0;
        long tmpDReadA = 0;
        long tmpDReadB = 0;
        int perReadTmp = 50; // This is changeable, how many character to read at once during temporary file reading.
        byte[] bufferR;
          
        try{
            RandomAccessFile FileA = new RandomAccessFile(afile, "r");
                FileWriter TmpA = new FileWriter(atmp);
                    bufferR = new byte[(FileA.length() - 0 > perReadTmp? perReadTmp : (int)(FileA.length() - 0))];
                    FileA.read(bufferR);
                    readA = new String(bufferR);
                    isaNeg = readA.charAt(0) == '-';
                    readA = readA.replaceAll("^[-+]+", "");
                    readA = readA.trim();
                    dAfterDecA = readA.indexOf('.');
                    dAfterDecA = dAfterDecA > -1? readA.length() - 1 - dAfterDecA : dAfterDecA;
                    if (dAfterDecA > -1){
                        readA = readA.replaceAll("[.]", "");
                    }
                    TmpA.write(readA);

                    while (FileA.getFilePointer() < FileA.length() ){
                        bufferR = new byte[(FileA.length() - FileA.getFilePointer() > perReadTmp? perReadTmp : (int)(FileA.length() - FileA.getFilePointer()))];
                        FileA.read(bufferR);
                        readA = new String(bufferR);
                        readA = readA.trim();
                        if (dAfterDecA < 0){
                            dAfterDecA = readA.indexOf(".");
                            dAfterDecA = dAfterDecA > -1? readA.length() - 1 - dAfterDecA : -1;
                            if (dAfterDecA > -1){
                                readA = readA.replaceAll("[.]", "");
                            }
                        } else {
                            tmpDReadA = readA.length();
                            dAfterDecA = dAfterDecA + tmpDReadA;
                        }
                        TmpA.write(readA);
                    }
                TmpA.close();
            FileA.close();
        } catch (IOException e) {
            throw new IllegalArgumentException("Unable to process " + afile + "file" , e);
        }
          
        try{
            RandomAccessFile FileB = new RandomAccessFile(bfile, "r");
                FileWriter TmpB = new FileWriter(btmp);
                    bufferR = new byte[(FileB.length() - 0 > perReadTmp? perReadTmp : (int)(FileB.length() - 0))];
                    FileB.read(bufferR);
                    readB = new String(bufferR);
                    isbNeg = readB.charAt(0) == '-';
                    readB = readB.replaceAll("^[-+]+", "");
                    readB = readB.trim();

                    dAfterDecB = readB.indexOf('.');
                    dAfterDecB = dAfterDecB > -1? readB.length() - 1 - dAfterDecB : dAfterDecB;
                    if (dAfterDecB > -1){
                        readB = readB.replaceAll("[.]", "");
                        
                    }
                    TmpB.write(readB);

                    while (FileB.getFilePointer() < FileB.length() ){
                        bufferR = new byte[(FileB.length() - FileB.getFilePointer() > perReadTmp? perReadTmp : (int)(FileB.length() - FileB.getFilePointer()))];
                        FileB.read(bufferR);
                        readB = new String(bufferR);
                        readB = readB.trim();
                        if (dAfterDecB < 0){
                            dAfterDecB = readB.indexOf(".");
                            dAfterDecB = dAfterDecB > -1? readB.length() - 1 - dAfterDecB : -1;
                            if (dAfterDecB > -1){
                                readB = readB.replaceAll("[.]", "");
                            }
                        } else {
                            tmpDReadB = readB.length();
                            dAfterDecB = dAfterDecB + tmpDReadB;
                        }
                        TmpB.write(readB);
                    }
                TmpB.close();
            FileB.close();
        } catch (IOException e) {
            throw new IllegalArgumentException("Unable to process " + bfile + " file" , e);
        }
          
        String pad0 = "";
        dAfterDecA = (dAfterDecA < 0)? 0 : dAfterDecA;
        dAfterDecB = (dAfterDecB < 0)? 0 : dAfterDecB;
        dAfterDecT = dAfterDecA + dAfterDecB;
        int digit = 9; // This is the amount of digits to calculate per cycle.
        long atmpsize = new File(atmp).length();
        long btmpsize = new File(btmp).length();
        long premakeoutlen = (atmpsize + btmpsize) + (digit * 2);

        while (pad0.length() < (digit - 1)){
            pad0 = "0".concat(pad0);
        }
          // This code is for the even of someone setting the digit variable to 1.
          // The event most likely not to occur. nevertheless being able to set the digit variable to one also offer the greatest backward compatibility in technology.
        String pad0tmp = pad0.length() < 1? "0" : pad0 ;
        int digittmp = digit < 1? 1 : digit - 1;
          
        try{
            FileWriter OutputTmp = new FileWriter(outputtmp);
                long idn = 0;
                while (idn < premakeoutlen){
                    OutputTmp.write(pad0tmp);
                        idn = idn + digittmp;
                }
            OutputTmp.close();
        } catch (IOException e) {
            throw new IllegalArgumentException("Unable to create " + outputtmp + " file" , e);
        }
          
        long a = 0;
        long b = 0;
        long o = 0;
        long posrB = 1;
        long posrO = 1;
        long loopidxB = 1;
        long temp = 0;
        long tempadd = 0;
        long blen = btmpsize;
        long alen = 0;
        long posrA = 0;
        long leftover = 0;
        long remainder = 0;
        long loopidxA = 0;
        long olen = new File(outputtmp).length();
        byte[] bufferC = new byte[digit];
        String tempaddstr = "";
        String tempstr = "";
        String leftoverstr = "";
        
        try{
            RandomAccessFile TmpB = new RandomAccessFile(btmp, "r");
                while (posrB != 0){
                    alen = atmpsize;
                    posrA = 1;
                    leftover = 0;
                    remainder = 0;
                    loopidxA = 1;
                    posrB = blen - (loopidxB * digit);

                    bufferC = new byte[(posrB > 0? digit : digit + (int)(posrB))];
                    TmpB.seek(posrB > 0? posrB : 0);
                    TmpB.read(bufferC);
                    b = Long.parseLong(new String(bufferC));
                    RandomAccessFile TmpA = new RandomAccessFile(atmp, "r");
                        RandomAccessFile OutputTmp = new RandomAccessFile(outputtmp, "rw");
                            while (posrA != 0){
                                posrO = olen - ((loopidxA + loopidxB - 1) * digit);
                                posrA = alen - (loopidxA * digit);

                                bufferC = new byte[(posrA > 0? digit : digit + (int)(posrA))];
                                TmpA.seek((posrA > 0? posrA : 0));
                                TmpA.read(bufferC);
                                a = Long.parseLong(new String(bufferC));

                                
                                temp = (b * a + remainder + leftover);
                                tempstr = String.valueOf(temp);
                                leftover = tempstr.length() > digit? Long.parseLong(tempstr.substring(0,tempstr.length() - digit)) : 0;
                                tempstr = pad0.concat(tempstr);

                                
                                bufferC = new byte[digit];
                                OutputTmp.seek(posrO);
                                OutputTmp.read(bufferC);
                                o = Long.parseLong(new String(bufferC));
                                        
                                tempadd = Long.parseLong(tempstr.substring(tempstr.length() - digit )) + o;
                                tempaddstr = String.valueOf(tempadd);
                                remainder = tempaddstr.length() > digit? Long.parseLong(tempaddstr.substring(0,tempaddstr.length() - digit)) : 0;
                                tempaddstr = pad0.concat(tempaddstr);
                                OutputTmp.seek(posrO);
                                OutputTmp.writeBytes(tempaddstr.substring(tempaddstr.length() - digit));
                                
                                posrA = posrA > 0? posrA : 0;
                                loopidxA = loopidxA + 1;
                            }
                            if (remainder + leftover > 0){
                                posrO = posrO - digit;
                                leftoverstr = pad0.concat(String.valueOf(leftover + remainder));
                                OutputTmp.seek(posrO);
                                OutputTmp.writeBytes(leftoverstr.substring(leftoverstr.length() - digit));
                            }
                        OutputTmp.close();
                    TmpA.close();
                    posrB = posrB > 0? posrB : 0;
                    loopidxB = loopidxB + 1;
                }
            TmpB.close();
        } catch (IOException e) {
            throw new IllegalArgumentException("Unable to process caculation for " + afile + " file and " + bfile + " file." , e);
        }
        
        boolean lead0End = false;
        long dBeforeDec = olen - dAfterDecT;
        long posw = 0;
        long truncatediff = 0;
        long truncatelen = 0;
        String readOutputTmp = "";
        String checker = "" ;
        String truncatestr = "";
        
        try{
            RandomAccessFile OutputTmp = new RandomAccessFile(outputtmp, "r");
                FileWriter Output = new FileWriter(outputfile);
                    if (isaNeg != isbNeg){
                        Output.write("-");
                    }
                    while (posw < dBeforeDec){
                        bufferR = new byte[(posw + perReadTmp < dBeforeDec? perReadTmp : (int)(dBeforeDec - posw))];
                        OutputTmp.seek(posw);
                        OutputTmp.read(bufferR);
                        readOutputTmp = new String(bufferR);
                        if (lead0End == false){
                            readOutputTmp = readOutputTmp.replaceAll("^0+", "");
                            lead0End = readOutputTmp.length() > 0? true : false;
                        }
                        Output.write(readOutputTmp);
                        posw = (posw + perReadTmp < dBeforeDec)? posw + perReadTmp : dBeforeDec;
                    }
                Output.close();
                
                
                long outputlen = new File(outputfile).length();
                RandomAccessFile Output2 = new RandomAccessFile(outputfile, "rw");
                    if (outputlen < 2){
                        bufferR = new byte[1];
                        Output2.read(bufferR);
                        checker = new String(bufferR);
                        if (outputlen < 1 || checker.equals("-")){
                            Output2.seek(Output2.length());
                            Output2.writeByte('0');
                        }
                    }

                    if (dAfterDecT > 0){
                        Output2.seek(Output2.length());
                        Output2.writeByte('.');
                    }
                    
                    Output2.seek(Output2.length());
                    while (posw < olen){
                        OutputTmp.seek(posw);
                        bufferR = new byte[(olen - posw > perReadTmp? perReadTmp : (int)(olen - OutputTmp.getFilePointer()))];
                        OutputTmp.read(bufferR);
                        readOutputTmp = new String(bufferR);
                        truncatestr = readOutputTmp;
                        truncatestr = readOutputTmp.replaceAll("0+$", "");
                        truncatediff = readOutputTmp.length() - truncatestr.length();
                        truncatelen = truncatediff == readOutputTmp.length()? truncatediff + truncatelen : truncatediff;
                        Output2.writeBytes(readOutputTmp);
                        posw = posw + perReadTmp;
                    }        

                    outputlen = Output2.length();    
                    Output2.setLength(outputlen - truncatelen);
                    outputlen = Output2.length();
                    Output2.seek(outputlen - 1);
                    bufferR = new byte[1];
                    Output2.read(bufferR);
                    readOutputTmp = new String(bufferR);
                    if (readOutputTmp.equals(".")){
                        Output2.setLength(outputlen - 1);
                    }
                Output2.close();
            OutputTmp.close();
            
        } catch (IOException e) {
            throw new IllegalArgumentException("Unable to process result file." , e);
        }
    }
      
}
Advertisement


Random Article You May Like