initial commit

This commit is contained in:
Sebastian Seedorf
2020-12-06 19:00:51 +01:00
commit 2234d5e7c5
12 changed files with 375 additions and 0 deletions

109
.gitignore vendored Normal file
View File

@@ -0,0 +1,109 @@
# Created by https://www.toptal.com/developers/gitignore/api/intellij
# Edit at https://www.toptal.com/developers/gitignore?templates=intellij
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
# https://plugins.jetbrains.com/plugin/7973-sonarlint
.idea/**/sonarlint/
# SonarQube Plugin
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
.idea/**/sonarIssues.xml
# Markdown Navigator plugin
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator-enh.xml
.idea/**/markdown-navigator/
# Cache file creation bug
# See https://youtrack.jetbrains.com/issue/JBR-2257
.idea/$CACHE_FILE$
# CodeStream plugin
# https://plugins.jetbrains.com/plugin/12206-codestream
.idea/codestream.xml
# End of https://www.toptal.com/developers/gitignore/api/intellij

View File

@@ -0,0 +1,8 @@
<component name="ArtifactManager">
<artifact type="jar" name="KaratsubaBigInteger:jar">
<output-path>$PROJECT_DIR$/out/artifacts/KaratsubaBigInteger_jar</output-path>
<root id="archive" name="KaratsubaBigInteger.jar">
<element id="module-output" name="KaratsubaBigInteger" />
</root>
</artifact>
</component>

23
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<option name="DEFAULT_COMPILER" value="Javac" />
<resourceExtensions />
<wildcardResourcePatterns>
<entry name="!?*.java" />
<entry name="!?*.form" />
<entry name="!?*.class" />
<entry name="!?*.groovy" />
<entry name="!?*.scala" />
<entry name="!?*.flex" />
<entry name="!?*.kt" />
<entry name="!?*.clj" />
</wildcardResourcePatterns>
<annotationProcessing>
<profile default="true" name="Default" enabled="false">
<processorPath useClasspath="true" />
</profile>
</annotationProcessing>
</component>
</project>

1
.idea/description.html generated Normal file
View File

@@ -0,0 +1 @@
<html>Simple <b>Java</b> application that includes a class with <code>main()</code> method</html>

5
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
</project>

7
.idea/kotlinc.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinCommonCompilerArguments">
<option name="languageVersion" value="1.1" />
<option name="apiVersion" value="1.1" />
</component>
</project>

12
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0" />
</component>
<component name="ProjectKey">
<option name="state" value="project://63537948-39a4-48a0-9c97-34259a0fa913" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/KaratsubaBigInteger.iml" filepath="$PROJECT_DIR$/KaratsubaBigInteger.iml" />
</modules>
</component>
</project>

7
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="" />
</component>
</project>

12
KaratsubaBigInteger.iml Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

3
src/META-INF/MANIFEST.MF Normal file
View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Main-Class: de.sebse.karatsubabiginteger.Main

View File

@@ -0,0 +1,180 @@
package de.sebse.karatsubabiginteger;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
static final int LONG_SHIFT = (int) Math.pow(10, (int) Math.log10(Long.MAX_VALUE)/2-1);
//100000000, Die etwas weniger als die Hälfte eines Long als 10er Potenz
public static void main(String[] args) {
//main für Zeittest
/*long zeit=0;
long z=0;
for (int i=0;i<100;i++){
z=testTime(9000);
System.out.println(z+ " Millisek.");
zeit=zeit+ z;
System.out.println("i:"+i);
}
System.out.println(((long) zeit/100)+ " Millisek.");*/
//main für eingabe über die Console
Scanner scanner = new Scanner(System.in);
System.out.println("Number 1: ");
BigInteger a = scanner.nextBigInteger();
System.out.println("Number 2: ");
BigInteger b = scanner.nextBigInteger();
System.out.println("Ergebnis der BigInteger Multiplikation:");
System.out.println(a.multiply(b));
System.out.println("Ergebnis der karatsuba Multiplikation:");
System.out.println(karatsubaMultiplication(a, b));
}
public static Long testTime(int n){//Funktion zum zeitmessen wie lange an einer Multiplikation gerechnet wird
String zufallszahl = "";
for (int i=0; i<n/10;i++){//Zufallszahlen erzeugen
zufallszahl=zufallszahl + String.valueOf((int) (Math.random()*Math.pow(10,17)));
}
BigInteger a = new BigInteger(zufallszahl);
zufallszahl = "";
for (int i=0; i<n/10;i++){
zufallszahl=zufallszahl + String.valueOf((int) (Math.random()*Math.pow(10,17)));
}
BigInteger b = new BigInteger(zufallszahl);
System.out.println(zufallszahl.length());
split(a);
split(b);
final long timeStart = System.currentTimeMillis();
System.out.println(karatsubaMultiplication(a, b));
final long timeEnd = System.currentTimeMillis();
return timeEnd - timeStart;
}
private static BigInteger karatsubaMultiplication(BigInteger a, BigInteger b) {//Muss für die Karatsuba-Multiplikation aufgerufen werden (main)
List<Long> lista = split(a);
List<Long> listb = split(b);
return merge(multiply(lista, listb, 0, 0, listb.size()));
}
private static List<Long> multiply(List<Long> a, List<Long> b, long startA, long startB, long len) {//rekusiver Karatsuba-Algorithmus
if (a.size()!=a.size())
throw new IllegalArgumentException();
// size(a) have to equals size(b)
if (len==1) {
List<Long> ret = new ArrayList<>(); // size(ret) in {1, 2}
long value = a.get((int) startA)*b.get((int) startB);
long carry = value / LONG_SHIFT;
ret.add(value % LONG_SHIFT);
if (carry != 0)
ret.add(carry);
return ret;
} else {
long endA = startA+len;
long endB = startB+len;
long midA = startA+len/2;
long midB = startB+len/2;
// A-low + A-high
List<Long> addA = add(a.subList((int) startA, (int) midA), a.subList((int) midA, (int) endA));
// B-low + B-high
List<Long> addB = add(b.subList((int) startB, (int) midB), b.subList((int) midB, (int) endB));
while (addA.size()>addB.size())
addB.add((long) 0);
while (addB.size()>addA.size())
addA.add((long) 0);
List<Long> retC = multiply(addA, addB, 0, 0, addA.size());
// A-low * B-low
List<Long> retA = multiply(a, b, startA, startB, midA-startA);
// A-high * B-high
List<Long> retB = multiply(a, b, midA, midB, len-(midA-startA));
retC = sub(retC, add(retA, retB));
return add(add(retB, retC, len/2), retA, len/2);
}
}
private static List<Long> sub(List<Long> a, List<Long> b) {//Subtrahieren zweier long[]
// if b smaller than a
for (int i = 0; i < b.size(); i++) {
b.set(i, -b.get(i));
}
return add(a, b);
}
private static List<Long> add(List<Long> a, List<Long> b) {
return add(a, b, 0);
}
private static List<Long> add(List<Long> a, List<Long> b, long shiftA) {//Addieren zweier Long[],
// a kann noch mit shiftA verschoben werden und die Zahlen können unterschiedlich lang sein
List<Long> ret = new ArrayList<>();
long offsetB = 0;
for (; offsetB < shiftA; offsetB++) {
if (offsetB>=b.size())
ret.add((long) 0);
else
ret.add(b.get((int) offsetB));
}
long offsetA = 0;
long carry = 0;
// a[i]+b[i]
for (; offsetB < b.size() && offsetA < a.size(); offsetB++, offsetA++) {
long value = b.get((int) offsetB)+a.get((int) offsetA)+carry;
carry = value / LONG_SHIFT;
ret.add(value % LONG_SHIFT);
}
// b ist länger als a
for (; offsetB < b.size(); offsetB++) {
long value = b.get((int) offsetB)+carry;
carry = value / LONG_SHIFT;
ret.add(value % LONG_SHIFT);
}
// a ist länger als b
for (; offsetA < a.size(); offsetA++) {
long value = a.get((int) offsetA)+carry;
carry = value / LONG_SHIFT;
ret.add(value % LONG_SHIFT);
}
// Evtl. zusätzliche Stelle durch Übertrag
if (carry != 0)
ret.add(carry);
return ret;
}
private static List<Long> split(BigInteger a) {//spaltet ein BigInteger in ein Long ArrayList auf
BigInteger b = BigInteger.valueOf(LONG_SHIFT);
List<Long> list = new ArrayList<>();
//noinspection ComparatorResultComparison
while (a.compareTo(b) != -1) {
list.add(a.mod(b).longValue());
a = a.divide(b);
}
list.add(a.longValueExact());
return list;
}
private static BigInteger merge(List<Long> list) {//Ergebnis zusammen fügen
BigInteger result = new BigInteger("0");
int count = 0;
for (Long val: list) {
result = result.add(BigInteger.valueOf(val).multiply(BigInteger.valueOf(LONG_SHIFT).pow(count)));
count++;
}
return result;
}
}