commit 2234d5e7c5f59924d0ed7349bc18ce3af24d8d92 Author: Sebastian Seedorf Date: Sun Dec 6 19:00:51 2020 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4d532a4 --- /dev/null +++ b/.gitignore @@ -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 + diff --git a/.idea/artifacts/KaratsubaBigInteger_jar.xml b/.idea/artifacts/KaratsubaBigInteger_jar.xml new file mode 100644 index 0000000..1c1fceb --- /dev/null +++ b/.idea/artifacts/KaratsubaBigInteger_jar.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/out/artifacts/KaratsubaBigInteger_jar + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..217af47 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/.idea/description.html b/.idea/description.html new file mode 100644 index 0000000..db5f129 --- /dev/null +++ b/.idea/description.html @@ -0,0 +1 @@ +Simple Java application that includes a class with main() method \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..e206d70 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml new file mode 100644 index 0000000..1c24f9a --- /dev/null +++ b/.idea/kotlinc.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..de8f7c7 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..acd1054 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..def6a6a --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/KaratsubaBigInteger.iml b/KaratsubaBigInteger.iml new file mode 100644 index 0000000..d5c0743 --- /dev/null +++ b/KaratsubaBigInteger.iml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..b70704e --- /dev/null +++ b/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: de.sebse.karatsubabiginteger.Main + diff --git a/src/de/sebse/karatsubabiginteger/Main.java b/src/de/sebse/karatsubabiginteger/Main.java new file mode 100644 index 0000000..b1478eb --- /dev/null +++ b/src/de/sebse/karatsubabiginteger/Main.java @@ -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 lista = split(a); + List listb = split(b); + return merge(multiply(lista, listb, 0, 0, listb.size())); + } + + private static List multiply(List a, List 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 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 addA = add(a.subList((int) startA, (int) midA), a.subList((int) midA, (int) endA)); + // B-low + B-high + List 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 retC = multiply(addA, addB, 0, 0, addA.size()); + + // A-low * B-low + List retA = multiply(a, b, startA, startB, midA-startA); + // A-high * B-high + List 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 sub(List a, List 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 add(List a, List b) { + return add(a, b, 0); + } + + private static List add(List a, List b, long shiftA) {//Addieren zweier Long[], + // a kann noch mit shiftA verschoben werden und die Zahlen können unterschiedlich lang sein + List 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 split(BigInteger a) {//spaltet ein BigInteger in ein Long ArrayList auf + BigInteger b = BigInteger.valueOf(LONG_SHIFT); + List 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 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; + } +} \ No newline at end of file