fixed bug where n3 is even and added tests

This commit is contained in:
Reborn 2025-03-12 17:31:24 +00:00
parent f33402c916
commit 9013cfb8d3
5 changed files with 147 additions and 73 deletions

View File

@ -1,8 +1,17 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Karatsuba</groupId>
<artifactId>KaratsubaImplementation</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Karatsuba implementation</name>
<description>Karatsuba implementation</description>
<dependencies>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,77 +1,13 @@
package karatsuba;
public class Karatsuba {
public interface Karatsuba {
//
public int multiply(int x, int y);
public int multiply(int x, int y) {
int result;
if (x < 10 && y < 10) {
result = x*y;
return result;
}
String[] xyStr = intNormalizer(x, y);
int n = xyStr[0].length();
int[] abcd = intFragmenter(xyStr, n);
int a = abcd[0];
int b = abcd[1];
int c = abcd[2];
int d = abcd[3];
int ac = multiply(a, c);
int bd = multiply(b, d);
int ADPlusBC = multiply(a+b,c+d) - ac - bd;
int tenFactorOne = (int) Math.pow(10, n);
int tenFactorTwo = (int) Math.pow(10, n/2);
int firstFactor = tenFactorOne*ac;
int secondFactor = tenFactorTwo*ADPlusBC;
// 10^nAC + 10^(n/2)(AD + BC) + BD
result = firstFactor + secondFactor + bd;
return result;
}
// This method exists to add left zeroes to the strings to make their size even and equal. n must be even.
String[] intNormalizer(int x, int y);
// this method returns an array that contains abcd for the karatsuba formula
public int[] intFragmenter(String[] xyStr, int n) {
int strHalfPoint = n/2;
if (strHalfPoint == 1) {
int a = Integer.parseInt(String.valueOf(xyStr[0].charAt(0)));
int b = Integer.parseInt(String.valueOf(xyStr[0].charAt(1)));
int c = Integer.parseInt(String.valueOf(xyStr[1].charAt(0)));
int d = Integer.parseInt(String.valueOf(xyStr[1].charAt(1)));
return new int[] {a, b, c, d};
}
int a = Integer.parseInt(xyStr[0].substring(0, strHalfPoint));
int b = Integer.parseInt(xyStr[0].substring(strHalfPoint));
int c = Integer.parseInt(xyStr[1].substring(0, strHalfPoint));
int d = Integer.parseInt(xyStr[1].substring(strHalfPoint));
return new int[] {a, b, c, d};
}
// This method exists to add left zeroes to the strings to make their size even and equal
public String[] intNormalizer(int x, int y) {
String xStr = Integer.toString(x);
String yStr = Integer.toString(y);
int xSize = xStr.length();
int ySize = yStr.length();
while (!isEven(xSize) || !isEven(ySize) || xSize != ySize) {
if (!isEven(xSize) || (xSize < ySize)) {
xStr = addLeftZero(xStr);
xSize = xStr.length();
}
if (!isEven(ySize) || (ySize < xSize)) {
yStr = addLeftZero(yStr);
ySize = yStr.length();
}
}
return new String[] {xStr, yStr};
}
public String addLeftZero(String str) {
return "0" + str;
}
public boolean isEven(int numb) {
if (numb/2==0) {
return false;
}
return true;
}
int[] intFragmenter(String[] xyStr, int n);
}

View File

@ -0,0 +1,80 @@
package karatsuba;
public class KaratsubaImplementation implements Karatsuba {
@Override
public int multiply(int x, int y) {
int result;
if (x < 10 && y < 10) {
result = x*y;
return result;
}
String[] xyStr = intNormalizer(x, y);
int n = xyStr[0].length();
int[] abcd = intFragmenter(xyStr, n);
int a = abcd[0];
int b = abcd[1];
int c = abcd[2];
int d = abcd[3];
int ac = multiply(a, c);
int bd = multiply(b, d);
int ADPlusBC = multiply(a+b,c+d) - ac - bd;
int tenFactorOne = (int) Math.pow(10, n);
int tenFactorTwo = (int) Math.pow(10, n/2);
int firstFactor = tenFactorOne*ac;
int secondFactor = tenFactorTwo*ADPlusBC;
// 10^nAC + 10^(n/2)(AD + BC) + BD
result = firstFactor + secondFactor + bd;
return result;
}
// this method returns an array that contains abcd for the karatsuba formula
@Override
public int[] intFragmenter(String[] xyStr, int n) {
int strHalfPoint = n/2;
if (strHalfPoint == 1) {
int a = Integer.parseInt(String.valueOf(xyStr[0].charAt(0)));
int b = Integer.parseInt(String.valueOf(xyStr[0].charAt(1)));
int c = Integer.parseInt(String.valueOf(xyStr[1].charAt(0)));
int d = Integer.parseInt(String.valueOf(xyStr[1].charAt(1)));
return new int[] {a, b, c, d};
}
int a = Integer.parseInt(xyStr[0].substring(0, strHalfPoint));
int b = Integer.parseInt(xyStr[0].substring(strHalfPoint));
int c = Integer.parseInt(xyStr[1].substring(0, strHalfPoint));
int d = Integer.parseInt(xyStr[1].substring(strHalfPoint));
return new int[] {a, b, c, d};
}
// This method exists to add left zeroes to the strings to make their size even and equal
@Override
public String[] intNormalizer(int x, int y) {
String xStr = Integer.toString(x);
String yStr = Integer.toString(y);
int xSize = xStr.length();
int ySize = yStr.length();
while (!isEven(xSize) || !isEven(ySize) || xSize != ySize) {
if (!isEven(xSize) || (xSize < ySize)) {
xStr = addLeftZero(xStr);
xSize = xStr.length();
}
if (!isEven(ySize) || (ySize < xSize)) {
yStr = addLeftZero(yStr);
ySize = yStr.length();
}
}
return new String[] {xStr, yStr};
}
public String addLeftZero(String str) {
return "0" + str;
}
public boolean isEven(int numb) {
if (numb%2 != 0) {
return false;
}
return true;
}
}

View File

@ -5,7 +5,7 @@ public class Main {
// 10^nAC + 10^(n/2)(AD + BC) + BD
int x = 1234;
int y = 5678;
Karatsuba karatsuba = new Karatsuba();
Karatsuba karatsuba = new KaratsubaImplementation();
int result = karatsuba.multiply(x, y);
System.out.println(result);
}

View File

@ -0,0 +1,49 @@
package karatsuba;
import static org.junit.Assert.*;
import org.junit.Test;
public class KaratsubaImplementationTest {
private Karatsuba karatsuba = new KaratsubaImplementation();
@Test
public void singleDigitMultiplication() {
assertEquals(karatsuba.multiply(4, 7), 28);
}
@Test
public void doubleDigitMultiplication() {
assertEquals(karatsuba.multiply(21, 89), 1869);
}
@Test
public void tripleDigitMultiplication() {
assertEquals(karatsuba.multiply(313, 862), 269806);
}
@Test
public void quadDigitMultiplication() {
assertEquals(karatsuba.multiply(1234, 5678), 7006652);
}
@Test
public void quadDigitMultiplicationInverse() {
assertEquals(karatsuba.multiply(5678, 1234), 7006652);
}
@Test
public void fiveDigitMultiplication() {
assertEquals(karatsuba.multiply(45689, 752), 34358128);
}
@Test
public void sevenDigitMultiplication() {
assertEquals(karatsuba.multiply(34984916, 6521984), 2.28171062393e14);
}
@Test
public void unnevenSevenDigitMultiplication() {
long result = Long.parseLong("1125628350426");
assertEquals(karatsuba.multiply(3519, 319871654), result);
}
}