/** * Utility method to split the list into two * * @param left : Starting index for split * @param right : Ending index for the split * @return : Returns an object of the BigArithmetic class with the list split */ public G05_BigArithmetic split(int left, int right) { G05_BigArithmetic temp = new G05_BigArithmetic(); for (int i = left; i < right; i++) { temp.number.add(this.number.get(i)); } temp.effectiveSize = temp.number.size(); return temp; }
/** * DAC Algorithm to multiply two long numbers * * @param a : Input object of BigArithmetic class * @param b : Input object of BigArithmetic class * @return : Returns an object of the BigArithmetic class which is a product of the two inputs */ public static G05_BigArithmetic product(G05_BigArithmetic a, G05_BigArithmetic b) { // If any of the two lists is null return null if (a == null || b == null) { return null; } // We remove the MS zeros to get the effective size of the two numbers. G05_BigArithmetic x = a.removeMSZeros(); G05_BigArithmetic y = b.removeMSZeros(); /*If the size is zero, then the list is 0, so return zero - Multiply by zero */ if (x.effectiveSize == 0 || y.effectiveSize == 0) { return new G05_BigArithmetic(0L); } // Call the productBA for DAC G05_BigArithmetic c = productBA(x, y); return c; }
/** * Method to multiply the two Big Arithmetic objects * * @param a : Input - object of class BigArithmetic * @param b : Input - object of class BigArithmetic * @return : Returns the product of the two inputs. */ public static G05_BigArithmetic productBA(G05_BigArithmetic a, G05_BigArithmetic b) { int maxSize = Math.max(a.effectiveSize, b.effectiveSize); // Get the max size of the two lists // If max size is one - normal single digit multiplication if (maxSize <= 1) { return new G05_BigArithmetic(a.number.get(0) * b.number.get(0)); } // If any of the lists is small - pad zeros to make the size equal if (a.number.size() < maxSize) { a.addZero(maxSize - a.number.size()); } else if (b.number.size() < maxSize) { b.addZero(maxSize - b.number.size()); } // Get the middle of the two lists int mid = (maxSize + 1) / 2; // Find a1, a2, b1 and b2 G05_BigArithmetic a1 = a.split(0, mid); G05_BigArithmetic a2 = a.split(mid, maxSize); G05_BigArithmetic b1 = b.split(0, mid); G05_BigArithmetic b2 = b.split(mid, maxSize); G05_BigArithmetic temp1 = productBA(a1, b1); // a1*b1 G05_BigArithmetic temp2 = productBA(a2, b2); // a2*b2 G05_BigArithmetic temp12 = productBA(G05_BigArithmetic.add(a1, a2), G05_BigArithmetic.add(b1, b2)); // (a1+a2)*(b1+b2) // [(a1+a2)*(b1+b2) - {(a1*b1) + (a2*b2)}] G05_BigArithmetic temp = G05_BigArithmetic.subtract(temp12, G05_BigArithmetic.add(temp1, temp2)); temp12 = temp; // Pad zeroes - similar to raising to base temp12 = temp12.addLeastZero(mid); temp2 = temp2.addLeastZero(mid * 2); // Return the product while removing MS Zeros return G05_BigArithmetic.add(G05_BigArithmetic.add(temp2, temp12), temp1).removeMSZeros(); }
/** * Method to subtract two large numbers * * @param a : Input a - an object of the BigArithmetic Class. * @param b : Input b - Second object of the BigArithmetic Class. * @return : An object of the type BigArithmetic, that contains the result of the subtraction. */ public static G05_BigArithmetic subtract(G05_BigArithmetic a, G05_BigArithmetic b) { boolean sign = false, bo = false; // Two boolean flags to represent sign and borrow /* * If second number is bigger than first, swap the two and set sign to true * We will return zero if sign is still set to true - Level 1 - No negative nos. */ if (a.number.size() < b.number.size()) { G05_BigArithmetic t = b; b = a; a = t; sign = true; } /* * If the size of the two numbers are equal, then iterate to see if second is bigger than first. * If yes, swap and set sign as true like the previous case. * Else, we are good to continue with the subtraction, so break out of the loop. */ else if (a.number.size() == b.number.size()) { for (int i = a.number.size() - 1; i >= 0; i--) { if (a.number.get(i) < b.number.get(i)) { sign = true; G05_BigArithmetic t = b; b = a; a = t; continue; } else break; } } // Iterators for looping through the linked list. Iterator<Long> ita = a.number.iterator(); Iterator<Long> itb = b.number.iterator(); G05_BigArithmetic result = new G05_BigArithmetic(); Long diff, firstElement = nextElement(ita), secondElement = nextElement(itb); while (secondElement != null) { if (bo) { if (firstElement == 0) { firstElement = 9L; bo = true; } else { firstElement = firstElement - 1; bo = false; } } if (firstElement < secondElement) { firstElement += 10; bo = true; } diff = firstElement - secondElement; result.number.add(diff % B); firstElement = nextElement(ita); secondElement = nextElement(itb); } while (firstElement != null) { if (bo) { if (firstElement == 0) { firstElement = 9L; bo = true; } else { firstElement = firstElement - 1; bo = false; } } result.number.add(firstElement); firstElement = nextElement(ita); } // If sign, result is a negative number - so return zero if (sign) { return new G05_BigArithmetic(0L); } // Remove the most significant zeros from the list. result.removeMSZeros(); // If after removing the zeros the size is zero, we return the answer as zero if (result.effectiveSize == 0) { return new G05_BigArithmetic(0L); } return result; }