final static int DIGIT_NUMBER_PER_ELEMENT = 4;
final static int NUMBER_OF_ELEMENTS = 100;
final static int MAX_VALUE_PER_ELEMENT = (int) Math.pow(10, DIGIT_NUMBER_PER_ELEMENT) - 1;
pub fn to_complement(a: &BigInteger) -> BigInteger {
let mut c = [0; NUMBER_OF_ELEMENTS];
let mut iter = a.iter().copied().enumerate().rev();
for (d, e) in iter.by_ref() {
if e > 0 {
c[d] = MAX_VALUE_PER_ELEMENT - e + 1;
break;
}
}
for (d, e) in iter {
c[d] = MAX_VALUE_PER_ELEMENT - e;
}
c
}
public static int[] toComplement(final int[] a) {
final int[] c = new int[NUMBER_OF_ELEMENTS];
int d = NUMBER_OF_ELEMENTS - 1;
for (; d >= 0; --d) {
final int e = a[d];
if (e > 0) {
c[d] = MAX_VALUE_PER_ELEMENT - e + 1;
--d;
break;
}
}
for (; d >= 0; --d) {
final int e = a[d];
c[d] = MAX_VALUE_PER_ELEMENT - e;
}
return c;
}
function toComplement(a: number[]) {
const c = new Array<number>(NUMBER_OF_ELEMENTS);
let d = NUMBER_OF_ELEMENTS - 1;
for (; d >= 0;d--) {
const e = a[d];
if (e > 0) {
c[d] = MAX_VALUE_PER_ELEMENT - e + 1;
d -= 1;
break;
} else {
c[d] = 0;
}
}
for (; d >= 0;d--) {
const e = a[d];
c[d] = MAX_VALUE_PER_ELEMENT - e;
}
return c;
}
func ToComplement(a BigInteger) BigInteger {
var c BigInteger
d := NUMBER_OF_ELEMENTS - 1
for ; d >= 0; d-- {
e := a[d]
if e > 0 {
c[d] = MAX_VALUE_PER_ELEMENT - e + 1
d--
break
}
}
for ; d >= 0; d-- {
e := a[d]
c[d] = MAX_VALUE_PER_ELEMENT - e
}
return c
}
pub fn to_integer_string(a: &BigInteger) -> String {
let mut integer_string = String::new();
let a = if a[0] > MAX_VALUE_PER_ELEMENT >> 1 {
integer_string.push('-');
to_complement(a)
} else {
*a
};
let mut iter = a.iter().copied();
for e in iter.by_ref() {
if e > 0 {
integer_string.push_str(&e.to_string());
break;
}
}
for e in iter {
let s = e.to_string();
for _ in s.len()..DIGIT_NUMBER_PER_ELEMENT {
integer_string.push('0');
}
integer_string.push_str(&s);
}
if integer_string.is_empty() {
integer_string.push('0');
}
integer_string
}
public static String toIntegerString(int[] a) {
final StringBuilder numberString = new StringBuilder();
if (a[0] > (MAX_VALUE_PER_ELEMENT >> 1)) {
numberString.append('-');
a = toComplement(a);
}
int d = 0;
for (; d < NUMBER_OF_ELEMENTS; ++d) {
final int e = a[d];
if (e > 0) {
numberString.append(e);
++d;
break;
}
}
for (; d < NUMBER_OF_ELEMENTS; ++d) {
final int e = a[d];
final String s = String.valueOf(e);
for (int i = s.length(); i < DIGIT_NUMBER_PER_ELEMENT; ++i) {
numberString.append('0');
}
numberString.append(s);
}
if (numberString.length() == 0) {
return "0";
}
return numberString.toString();
}
function toIntegerString(a: number[]) {
let numberString = "";
if (a[0] > (MAX_VALUE_PER_ELEMENT >> 1)) {
numberString += "-";
a = toComplement(a);
}
let d = 0;
for (; d < NUMBER_OF_ELEMENTS;d++) {
const e = a[d];
if (e > 0) {
numberString += e.toString();
d += 1;
break;
}
}
for (; d < NUMBER_OF_ELEMENTS;d++) {
const e = a[d];
const s = e.toString();
for (let i = s.length;i < DIGIT_NUMBER_PER_ELEMENT;i++) {
numberString += "0";
}
numberString += s;
}
if (numberString.length === 0) {
return "0";
}
return numberString;
}
func ToIntegerString(a BigInteger) string {
numberString := ""
if a[0] > MAX_VALUE_PER_ELEMENT>>1 {
numberString += "-"
a = ToComplement(a)
}
d := 0
for ; d < NUMBER_OF_ELEMENTS; d++ {
e := a[d]
if e > 0 {
numberString += strconv.Itoa(e)
d++
break
}
}
for ; d < NUMBER_OF_ELEMENTS; d++ {
e := a[d]
s := strconv.Itoa(e)
for i := len(s); i < DIGIT_NUMBER_PER_ELEMENT; i++ {
numberString += "0"
}
numberString += s
}
if len(numberString) == 0 {
return "0"
}
return numberString
}
pub fn to_big_integer(mut n: &str) -> BigInteger {
let negative = if &n[0..1] == "-" {
n = &n[1..];
true
} else {
false
};
let mut a = [0; NUMBER_OF_ELEMENTS];
let mut d = 1;
let mut end = n.len();
while end > 0 {
let temp = end;
if end > DIGIT_NUMBER_PER_ELEMENT {
end -= DIGIT_NUMBER_PER_ELEMENT;
} else {
end = 0;
};
let e = &n[end..temp];
a[NUMBER_OF_ELEMENTS - d] = e.parse().unwrap();
d += 1;
}
if negative {
to_complement(&a)
} else {
a
}
}
public static int[] toBigInteger(String n) {
final boolean negative;
if (n.charAt(0) == '-') {
n = n.substring(1);
negative = true;
} else {
negative = false;
}
final int[] a = new int[NUMBER_OF_ELEMENTS];
int d = 1;
int end = n.length();
while (end > 0) {
final int temp = end;
if (end > DIGIT_NUMBER_PER_ELEMENT) {
end -= DIGIT_NUMBER_PER_ELEMENT;
} else {
end = 0;
}
final String e = n.substring(end, temp);
a[NUMBER_OF_ELEMENTS - d] = Integer.parseInt(e);
++d;
}
if (negative) {
return toComplement(a);
} else {
return a;
}
}
function toBigInteger(n: string) {
let negative = false;
if (n.startsWith("-")) {
n = n.substring(1);
negative = true;
}
const a = new Array<number>(NUMBER_OF_ELEMENTS).fill(0);
let d = 1;
let end = n.length;
while (end > 0) {
const temp = end;
if (end > DIGIT_NUMBER_PER_ELEMENT) {
end -= DIGIT_NUMBER_PER_ELEMENT;
} else {
end = 0;
}
const e = n.substring(end, temp);
a[NUMBER_OF_ELEMENTS - d] = parseInt(e);
d += 1;
}
if (negative) {
return toComplement(a);
} else {
return a;
}
}
func ToBigInteger(n string) BigInteger {
negative := false
if n[0:1] == "-" {
n = n[1:]
negative = true
}
var a BigInteger
d := 1
end := len(n)
for end > 0 {
temp := end
if end > DIGIT_NUMBER_PER_ELEMENT {
end -= DIGIT_NUMBER_PER_ELEMENT
} else {
end = 0
}
e := n[end:temp]
a[NUMBER_OF_ELEMENTS-d], _ = strconv.Atoi(e)
d++
}
if negative {
return ToComplement(a)
} else {
return a
}
}
pub fn add(a: &BigInteger, b: &BigInteger) -> BigInteger {
let mut sum = [0; NUMBER_OF_ELEMENTS];
let mut carry = 0;
for (d, y) in b.iter().copied().enumerate().rev() {
let x = a[d];
let mut z = x + y + carry;
if z > MAX_VALUE_PER_ELEMENT {
z -= MAX_VALUE_PER_ELEMENT + 1;
carry = 1;
} else {
carry = 0;
}
sum[d] = z;
}
sum
}
public static int[] add(final int[] a, final int[] b) {
final int[] sum = new int[NUMBER_OF_ELEMENTS];
int carry = 0;
for (int d = NUMBER_OF_ELEMENTS - 1; d >= 0; --d) {
final int x = a[d];
final int y = b[d];
int z = x + y + carry;
if (z > MAX_VALUE_PER_ELEMENT) {
z -= MAX_VALUE_PER_ELEMENT + 1;
carry = 1;
} else {
carry = 0;
}
sum[d] = z;
}
return sum;
}
function add(a: number[], b: number[]) {
const sum = new Array<number>(NUMBER_OF_ELEMENTS);
let carry = 0;
for (let d = NUMBER_OF_ELEMENTS - 1;d >= 0;d--) {
const x = a[d];
const y = b[d];
let z = x + y + carry;
if (z > MAX_VALUE_PER_ELEMENT) {
z -= MAX_VALUE_PER_ELEMENT + 1;
carry = 1;
} else {
carry = 0;
}
sum[d] = z;
}
return sum;
}
func Add(a BigInteger, b BigInteger) BigInteger {
var sum BigInteger
carry := 0
for d := NUMBER_OF_ELEMENTS - 1; d >= 0; d-- {
x := a[d]
y := b[d]
z := x + y + carry
if z > MAX_VALUE_PER_ELEMENT {
z -= MAX_VALUE_PER_ELEMENT + 1
carry = 1
} else {
carry = 0
}
sum[d] = z
}
return sum
}
pub fn subtract(a: &BigInteger, b: &BigInteger) -> BigInteger {
let mut difference = [0; NUMBER_OF_ELEMENTS];
let mut borrow = 0;
for (d, mut y) in b.iter().copied().enumerate().rev() {
let x = a[d];
y += borrow;
if x < y {
difference[d] = x + MAX_VALUE_PER_ELEMENT + 1 - y;
borrow = 1;
} else {
difference[d] = x - y;
borrow = 0;
}
}
difference
}
public static int[] subtract(final int[] a, final int[] b) {
final int[] difference = new int[NUMBER_OF_ELEMENTS];
int borrow = 0;
for (int d = NUMBER_OF_ELEMENTS - 1; d >= 0; --d) {
final int x = a[d];
final int y = b[d] + borrow;
if (x < y) {
difference[d] = x + MAX_VALUE_PER_ELEMENT + 1 - y;
borrow = 1;
} else {
difference[d] = x - y;
borrow = 0;
}
}
return difference;
}
function subtract(a: number[], b: number[]) {
const difference = new Array<number>(NUMBER_OF_ELEMENTS);
let borrow = 0;
for (let d = NUMBER_OF_ELEMENTS - 1;d >= 0;d--) {
const x = a[d];
const y = b[d] + borrow;
if (x < y) {
difference[d] = x + MAX_VALUE_PER_ELEMENT + 1 - y;
borrow = 1;
} else {
difference[d] = x - y;
borrow = 0;
}
}
return difference;
}
func Subtract(a BigInteger, b BigInteger) BigInteger {
var difference BigInteger
borrow := 0
for d := NUMBER_OF_ELEMENTS - 1; d >= 0; d-- {
x := a[d]
y := b[d] + borrow
if x < y {
difference[d] = x + MAX_VALUE_PER_ELEMENT + 1 - y
borrow = 1
} else {
difference[d] = x - y
borrow = 0
}
}
return difference
}
pub fn multiply(a: &BigInteger, b: &BigInteger) -> BigInteger {
let mut product = [0; NUMBER_OF_ELEMENTS];
let mut negative = false;
let a = if a[0] > MAX_VALUE_PER_ELEMENT >> 1 {
negative = true;
to_complement(a)
} else {
*a
};
let b = if b[0] > MAX_VALUE_PER_ELEMENT >> 1 {
negative = !negative;
to_complement(b)
} else {
*b
};
let mut carry = 0;
for (dy, y) in b.iter().copied().enumerate().rev() {
for (dx, x) in a.iter().copied().enumerate().rev() {
// d = NUMBER_OF_ELEMENTS - 1 - ((NUMBER_OF_ELEMENTS - 1 - dx) + (NUMBER_OF_ELEMENTS - 1 - dy))
let mut d = dx + dy + 1;
if d < NUMBER_OF_ELEMENTS {
break;
}
d -= NUMBER_OF_ELEMENTS;
let mut z = x * y + carry + product[d];
if z > MAX_VALUE_PER_ELEMENT {
carry = z / (MAX_VALUE_PER_ELEMENT + 1);
z %= MAX_VALUE_PER_ELEMENT + 1;
} else {
carry = 0;
}
product[d] = z;
}
}
if negative {
to_complement(&product)
} else {
product
}
}
public static int[] multiply(int[] a, int[] b) {
final int[] product = new int[NUMBER_OF_ELEMENTS];
boolean negative = false;
if (a[0] > (MAX_VALUE_PER_ELEMENT >> 1)) {
negative = true;
a = toComplement(a);
}
if (b[0] > (MAX_VALUE_PER_ELEMENT >> 1)) {
negative = !negative;
b = toComplement(b);
}
int carry = 0;
for (int dy = NUMBER_OF_ELEMENTS - 1; dy >= 0; --dy) {
final int y = b[dy];
for (int dx = NUMBER_OF_ELEMENTS - 1; dx >= 0; --dx) {
final int x = a[dx];
// d = NUMBER_OF_ELEMENTS - 1 - ((NUMBER_OF_ELEMENTS - 1 - dx) + (NUMBER_OF_ELEMENTS - 1 - dy))
int d = dx + dy + 1 - NUMBER_OF_ELEMENTS;
if (d < 0) {
break;
}
int z = x * y + carry + product[d];
if (z > MAX_VALUE_PER_ELEMENT) {
carry = z / (MAX_VALUE_PER_ELEMENT + 1);
z %= MAX_VALUE_PER_ELEMENT + 1;
} else {
carry = 0;
}
product[d] = z;
}
}
if (negative) {
return toComplement(product);
} else {
return product;
}
}
function multiply(a: number[], b: number[]) {
const product = new Array<number>(NUMBER_OF_ELEMENTS).fill(0);
let negative = false;
if (a[0] > (MAX_VALUE_PER_ELEMENT >> 1)) {
negative = true;
a = toComplement(a);
}
if (b[0] > (MAX_VALUE_PER_ELEMENT >> 1)) {
negative = !negative;
b = toComplement(b);
}
let carry = 0;
for (let dy = NUMBER_OF_ELEMENTS - 1;dy >= 0;dy--) {
const y = b[dy];
for (let dx = NUMBER_OF_ELEMENTS - 1;dx >= 0;dx--) {
const x = a[dx];
// d = NUMBER_OF_ELEMENTS - 1 - ((NUMBER_OF_ELEMENTS - 1 - dx) + (NUMBER_OF_ELEMENTS - 1 - dy))
const d = dx + dy + 1 - NUMBER_OF_ELEMENTS;
if (d < 0) {
break;
}
let z = (x * y) + carry + product[d];
if (z > MAX_VALUE_PER_ELEMENT) {
carry = Math.floor(z / (MAX_VALUE_PER_ELEMENT + 1));
z %= MAX_VALUE_PER_ELEMENT + 1;
} else {
carry = 0;
}
product[d] = z;
}
}
if (negative) {
return toComplement(product);
} else {
return product;
}
}
func Multiply(a BigInteger, b BigInteger) BigInteger {
var product BigInteger
negative := false
if a[0] > MAX_VALUE_PER_ELEMENT>>1 {
negative = true
a = ToComplement(a)
}
if b[0] > MAX_VALUE_PER_ELEMENT>>1 {
negative = !negative
b = ToComplement(b)
}
carry := 0
for dy := NUMBER_OF_ELEMENTS - 1; dy >= 0; dy-- {
y := b[dy]
for dx := NUMBER_OF_ELEMENTS - 1; dx >= 0; dx-- {
x := a[dx]
// d = NUMBER_OF_ELEMENTS - 1 - ((NUMBER_OF_ELEMENTS - 1 - dx) + (NUMBER_OF_ELEMENTS - 1 - dy))
d := dx + dy + 1 - NUMBER_OF_ELEMENTS
if d < 0 {
break
}
z := x*y + carry + product[d]
if z > MAX_VALUE_PER_ELEMENT {
carry = z / (MAX_VALUE_PER_ELEMENT + 1)
z %= MAX_VALUE_PER_ELEMENT + 1
} else {
carry = 0
}
product[d] = z
}
}
if negative {
return ToComplement(product)
} else {
return product
}
}
fn unsigned_compare(a: &BigInteger, b: &BigInteger) -> Ordering {
for (d, x) in a.iter().copied().enumerate() {
let y = b[d];
let cmp = x.cmp(&y);
if cmp != Ordering::Equal {
return cmp;
}
}
Ordering::Equal
}
static int unsignedCompare(int[] a, int[] b) {
for (int d = 0; d < NUMBER_OF_ELEMENTS; ++d) {
final int x = a[d];
final int y = b[d];
final int cmp = x - y;
if (cmp != 0) {
return cmp;
}
}
return 0;
}
回傳值若大於0,表示a > b;回傳值若小於0,表示a < b;回傳值若等於0,表示a = b。
function unsignedCompare(a: number[], b: number[]) {
for (let d = 0;d < NUMBER_OF_ELEMENTS;d++) {
const x = a[d];
const y = b[d];
const cmp = x - y;
if (cmp !== 0) {
return cmp;
}
}
return 0;
}
回傳值若大於0,表示a > b;回傳值若小於0,表示a < b;回傳值若等於0,表示a = b。
func unsignedCompare(a BigInteger, b BigInteger) int {
for d, x := range a {
y := b[d]
cmp := x - y
if cmp != 0 {
return cmp
}
}
return 0
}