Wednesday, 29 July 2015

Java program to perform 64-bits numbers multiplication using shared memory concept

/*
    Title: Java program to perform 64-bits numbers multiplication using memorymapped files and utility classes
    -- Memorymapped files have been used to simulate shared memory concepts in Java. Multiple threads can be though of other alternative here
    -- 19 digits input is accepted which in turns represent 64-bits
    -- School multiplication methos is applied
    -- For simplicity block of 8 bytes is used for multiplication
*/




import java.util.*;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;

class Multiplication64Bits{

    /* converting string to digits    */
    private static byte[] stringToDigits(String num) {
        byte[] result = new byte[num.length()];
        for (int i = 0; i < num.length(); i++) {
            char c = num.charAt(i);
            if (c < '0' || c > '9') {
                throw new IllegalArgumentException("Invalid digit " + c
                        + " found at position " + i);
            }
            result[num.length() - 1 - i] = (byte) (c - '0');
        }
        return result;
    }

    /* Deinition of longmult()    */
    public static String longMult(String num1, String num2) {
        byte[] left = stringToDigits(num1);
        byte[] right = stringToDigits(num2);
        byte[] result = new byte[left.length + right.length];
        for (int rightPos = 0; rightPos < right.length; rightPos++) {
            byte rightDigit = right[rightPos];
            byte temp = 0;
            for (int leftPos = 0; leftPos < left.length; leftPos++) {
                temp += result[leftPos + rightPos];
                temp += rightDigit * left[leftPos];
                result[leftPos + rightPos] = (byte) (temp % 10);
                temp /= 10;
            }
            int destPos = rightPos + left.length;
            while (temp != 0) {
                temp += result[destPos] & 0xFFFFFFFFL;
                result[destPos] = (byte) (temp % 10);
                temp /= 10;
                destPos++;
            }
        }
        StringBuilder stringResultBuilder = new StringBuilder(result.length);
        for (int i = result.length - 1; i >= 0; i--) {
            byte digit = result[i];
            if (digit != 0 || stringResultBuilder.length() > 0) {
                stringResultBuilder.append((char) (digit + '0'));
            }
        }
        return stringResultBuilder.toString();
    }
    public static void main(String args[]) throws Exception{
        Scanner scan = new Scanner(System.in);       
        System.out.println("Enter First Multiplier ");   
       
        String input = scan.nextLine();

        BufferedWriter writer = new BufferedWriter(new FileWriter("InputFile")); // InputFile is file which holds multiplier
        writer.write(input);
        writer.close();   

        // Reading from memorymapped files

        File file = new File("InputFile");
        FileChannel fc = new RandomAccessFile(file, "rw").getChannel();
        ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, (int) fc.size());

        String num1 = null;
        String token, multiplier1, multiplier2;
        char ch;       

        while (bb.hasRemaining()) {
            ch = (char) bb.get();
            num1 = num1 + ch;
        }
        token  = num1.substring(4);
        multiplier1 = multiplier2 = token;
        System.out.println("Multiplier1: " + multiplier1);
        System.out.println("Multiplier2: " + multiplier2);

        System.out.println("Final Result: " + longMult(multiplier1,multiplier2)); //calling longmult function
    }
}

/*
        OUTPUT
[pavan@Pavan Multiplication]$ javac Multiplication64Bits.java
[pavan@Pavan Multiplication]$ java Multiplication64Bits
Enter First Multiplier
1234567891234567891
Multiplier1: 1234567891234567891
Multiplier2: 1234567891234567891
Final Result: 1524157878067367854031397857488187881
[pavan@Pavan Multiplication]$
*/

18 comments:

Unknown said...

Hello sir, could you please explain this line -
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, (int) fc.size());
what is the second parameter in map function?

Pavan Jaiswal said...

Hello Mam,
Second argument indicates the position within the file at which the mapped region is to start; must be non-negative.

For more details, you may refer the below link:
http://docs.oracle.com/javase/7/docs/api/java/nio/channels/FileChannel.html#map%28java.nio.channels.FileChannel.MapMode,%20long,%20long%29

Thanks.

Unknown said...

what is the difference between normal getBytes() method and your StringToDigit method ? why I shouldn't use getBytes()?

Pavan Jaiswal said...

Dear Dipak,

getBytes() method is used to encodes String into a sequence of bytes using the platform's default charset, storing the result into a new byte array.

In our program we have used user-defined method stringToDigit() which in turns returns byte array as we are doing byte by byte multiplication in program.

Now answering to your second question, you can even think of using getBytes(). It really depends on what business logic you would like to apply.

The only constraints is that you must have to use shared memory concept and must perform 64-bit numbers multiplication.

Thanks.

Unknown said...

Thank you. Found it interesting and useful. Java is a general purpose, high-level, class-based and object-oriented programming language. And we are the best Java training institute in Chennai.

geethu said...

To learn shorter programs when compared to Java then it is the right time to choose python training. There is increasing market demand for professionals who have completed python training.
python training in chennai | python training institutes in chennai

Anonymous said...

it is useful

Aurthur said...

Really a good post.
Java Training in chennai | Java course in chennai

Anonymous said...

why substring(4)??
why to skip first 4 char?

Anonymous said...

Because first 4 charterers are "N""U""L""L",so to avoid these character you can either you use substring(4) or initialize String num1 with empty string(String num1="";)

ben2299 said...

Why can't you simply use BigInteger for such large number multiplication.

Pavan Jaiswal said...

Reason behind not using BIgInteger directly is that we are performing 19 digit multiplication, so this much length number is not handled by Java. That's why we are using String and then converting it back to Byte.

Thanks.

ben2299 said...

BigInteger is used for handling numbers which are greater than 64-bit.
Correct me if i'am wrong sir!--->
public static void main(String[] args) {
BigInteger b1 = new BigInteger("9223372036854775807");
BigInteger b2 = new BigInteger("9223372036854775807");

BigInteger product = b1.multiply(b2);

System.out.println(product);


}

Anonymous said...

if we are giving multipler 1 as :::1234
and this number is reversed in this program as 4321 for exection

Anonymous said...

Sir if we are giving input for multiplier as 1234
and it is reversed as 4321 any were in program for execution please let me know .

Unknown said...

temp += result[destPos] & 0xFFFFFFFFL
Sir can you please explain this line?

Unknown said...

temp += result[destPos] & 0xFFFFFFFFL
Sir can you please explain this line?

Anonymous said...

it provides useful information