Created
October 14, 2019 14:01
-
-
Save Dimanaux/6242f9d161c4ce0fb5d7e7d725fa654a to your computer and use it in GitHub Desktop.
Long arithmetics example, + and * for natural numbers.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Scanner; | |
/** | |
* Natural numbers here are represented by byte arrays. | |
* They are stored reversed. Each byte represents decimal digit | |
* of the number. E. g. 456 = {6, 5, 4} | |
*/ | |
public class Main { | |
public static void main(String[] args) { | |
Scanner scanner = new Scanner(System.in); | |
byte[] a = readBigInt(scanner); | |
byte[] b = readBigInt(scanner); | |
printBigInt(multiply(a, b)); | |
printBigInt(plus(a, b)); | |
} | |
static void printBigInt(byte[] c) { | |
for (int i = c.length - 1; i >= 0; i--) { | |
System.out.print(c[i]); | |
} | |
System.out.println(); | |
} | |
static byte[] readBigInt(Scanner scanner) { | |
String numAsString = scanner.next(); | |
byte[] number = new byte[numAsString.length()]; | |
for (int i = 0; i < numAsString.length(); i++) { | |
char digit = numAsString.charAt(i); | |
number[number.length - i - 1] = (byte) (digit - '0'); | |
} | |
return number; | |
} | |
static byte[] multiply(byte[] a, byte[] b) { | |
byte[] product = new byte[] {0}; | |
byte[] timesLeft = truncate(b); | |
while (!isZero(timesLeft)) { | |
product = plus(product, a); | |
dec(timesLeft); | |
} | |
return truncate(product); | |
} | |
static byte[] plus(byte[] a, byte[] b) { | |
int resultMaxSize = max(a.length, b.length) + 1; | |
byte[] sum = new byte[resultMaxSize]; | |
byte next = 0; | |
for (int i = 0; i < resultMaxSize; i++) { | |
sum[i] = (byte) ((getOrZero(a, i) + getOrZero(b, i) + next) % 10); | |
next = (byte) ((getOrZero(a, i) + getOrZero(b, i) + next) / 10); | |
} | |
return truncate(sum); | |
} | |
/** | |
* Retrieves digit from the given number from given position. | |
* If there is no such position in number, returns 0. | |
*/ | |
static byte getOrZero(byte[] number, int position) { | |
if (position < number.length) { | |
return number[position]; | |
} else { | |
return 0; | |
} | |
} | |
static boolean isZero(byte[] number) { | |
for (int i = 0; i < number.length; i++) { | |
if (number[i] != 0) { | |
return false; | |
} | |
} | |
return true; | |
} | |
/** | |
* Truncates leading zeroes | |
* We can use it to copy big number | |
* @param number number can be either 00457 and 457 | |
* @return number with no leading zeroes e.g. 0457 -> 457 | |
*/ | |
static byte[] truncate(byte[] number) { | |
int size = number.length; | |
for (int i = number.length - 1; i >= 0 && number[i] == 0; i--) { | |
size--; | |
} | |
byte[] truncated = new byte[size]; | |
for (int i = 0; i < size; i++) { | |
truncated[i] = number[i]; | |
} | |
return truncated; | |
} | |
/** | |
* Decrease number by 1 | |
*/ | |
static void dec(byte[] number) { | |
int i = 0; | |
while (number[i] == 0) { | |
number[i] = 9; | |
i++; | |
} | |
number[i] -= 1; | |
} | |
static int max(int a, int b) { | |
if (a > b) { | |
return a; | |
} else { | |
return b; | |
} | |
} | |
static int min(int a, int b) { | |
if (a < b) { | |
return a; | |
} else { | |
return b; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment