2021-08-21 17:18:57 +03:00
|
|
|
module big
|
|
|
|
|
|
|
|
struct JS.BigInt {}
|
|
|
|
|
|
|
|
#const jsNumber = Number;
|
|
|
|
|
|
|
|
pub struct Number {
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn new() Number {
|
|
|
|
return Number{}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn from_int(i int) Number {
|
|
|
|
n := Number{}
|
|
|
|
#n.value = BigInt(+i)
|
|
|
|
|
|
|
|
return n
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn from_u64(u u64) Number {
|
|
|
|
n := Number{}
|
|
|
|
#n.value = BigInt(u.val)
|
|
|
|
|
|
|
|
return n
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn from_hex_string(input string) Number {
|
|
|
|
n := Number{}
|
|
|
|
#n.value = BigInt(input.val)
|
|
|
|
|
|
|
|
return n
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn from_string(input string) Number {
|
|
|
|
n := Number{}
|
|
|
|
#n.value = BigInt(input.val)
|
|
|
|
|
|
|
|
return n
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (n &Number) int() int {
|
|
|
|
r := 0
|
|
|
|
#r.val = jsNumber(n.val.value)
|
|
|
|
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (n &Number) str() string {
|
|
|
|
s := ''
|
|
|
|
#s.str = n.val.value + ""
|
|
|
|
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (a &Number) + (b &Number) Number {
|
|
|
|
c := Number{}
|
|
|
|
#c.value = a.val.value + b.val.value
|
|
|
|
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (a &Number) - (b &Number) Number {
|
|
|
|
c := Number{}
|
|
|
|
#c.value = a.val.value - b.val.value
|
|
|
|
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (a &Number) / (b &Number) Number {
|
|
|
|
c := Number{}
|
|
|
|
#c.value = a.val.value / b.val.value
|
|
|
|
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (a &Number) * (b &Number) Number {
|
|
|
|
c := Number{}
|
|
|
|
#c.value = a.val.value * b.val.value
|
|
|
|
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
pub fn (a &Number) % (b &Number) Number {
|
|
|
|
c := Number{}
|
|
|
|
# c.value = a.val.value % b.val.value
|
|
|
|
return c
|
|
|
|
}*/
|
|
|
|
|
2023-07-20 02:33:07 +03:00
|
|
|
pub fn div_mod(a &Number, b &Number) (Number, Number) {
|
2021-08-21 17:18:57 +03:00
|
|
|
c := Number{}
|
|
|
|
d := Number{}
|
|
|
|
#c.value = a.val.value / b.val.value
|
|
|
|
#d.value = a.val.value % b.val.value
|
|
|
|
|
|
|
|
return c, d
|
|
|
|
}
|
|
|
|
|
2023-07-20 02:33:07 +03:00
|
|
|
[deprecated: 'use div_mod(a, b) instead']
|
|
|
|
pub fn divmod(a &Number, b &Number) (Number, Number) {
|
|
|
|
return div_mod(a, b)
|
|
|
|
}
|
|
|
|
|
2021-08-21 17:18:57 +03:00
|
|
|
pub fn cmp(a &Number, b &Number) int {
|
|
|
|
res := 0
|
|
|
|
|
|
|
|
#if (a.val.value < b.val.value) res.val = -1
|
|
|
|
#else if (a.val.value > b.val.value) res.val = 1
|
|
|
|
#else res.val = 0
|
|
|
|
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (a &Number) is_zero() bool {
|
|
|
|
res := false
|
|
|
|
#res.val = a.val.value == BigInt(0)
|
|
|
|
|
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut a Number) inc() {
|
|
|
|
#a.val.value = a.val.value + BigInt(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (mut a Number) dec() {
|
|
|
|
#a.val.value = a.val.value - BigInt(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (a &Number) isqrt() Number {
|
|
|
|
b := Number{}
|
|
|
|
#let x0 = a.val.value >> 1n
|
|
|
|
#if (x0) {
|
|
|
|
#let x1 = (x0 + a.val.value / x0) >> 1n
|
|
|
|
#while (x1 < x0) {
|
|
|
|
#x0 = x1
|
|
|
|
#x1 = (x0 + a.val.value / x0) >> 1n
|
|
|
|
#}
|
|
|
|
#b.value = x0
|
|
|
|
#} else { b.value = a.val.value; }
|
|
|
|
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
2023-07-20 02:33:07 +03:00
|
|
|
[deprecated: 'use bitwise_and(a, b) instead']
|
2021-08-21 17:18:57 +03:00
|
|
|
pub fn b_and(a &Number, b &Number) Number {
|
2023-07-20 02:33:07 +03:00
|
|
|
return bitwise_and(a, b)
|
|
|
|
}
|
|
|
|
|
|
|
|
[deprecated: 'use bitwise_or(a, b) instead']
|
|
|
|
pub fn b_or(a &Number, b &Number) Number {
|
|
|
|
return bitwise_or(a, b)
|
|
|
|
}
|
|
|
|
|
|
|
|
[deprecated: 'use bitwise_xor(a, b) instead']
|
|
|
|
pub fn b_xor(a &Number, b &Number) Number {
|
|
|
|
return bitwise_xor(a, b)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn bitwise_and(a &Number, b &Number) Number {
|
2021-08-21 17:18:57 +03:00
|
|
|
c := Number{}
|
|
|
|
#c.value = a.val.value & b.val.value
|
|
|
|
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2023-07-20 02:33:07 +03:00
|
|
|
pub fn bitwise_or(a &Number, b &Number) Number {
|
2021-08-21 17:18:57 +03:00
|
|
|
c := Number{}
|
|
|
|
#c.value = a.val.value | b.val.value
|
|
|
|
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2023-07-20 02:33:07 +03:00
|
|
|
pub fn bitwise_xor(a &Number, b &Number) Number {
|
2021-08-21 17:18:57 +03:00
|
|
|
c := Number{}
|
|
|
|
#c.value = a.val.value ^ b.val.value
|
|
|
|
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2023-07-20 02:33:07 +03:00
|
|
|
[deprecated: 'use a.left_shift(amount) instead']
|
|
|
|
pub fn (a &Number) lshift(amount int) Number {
|
|
|
|
return a.left_shift(amount)
|
|
|
|
}
|
|
|
|
|
|
|
|
[deprecated: 'use a.right_shift(amount) instead']
|
|
|
|
pub fn (a &Number) rshift(amount int) Number {
|
|
|
|
return a.right_shift(amount)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (a &Number) left_shift(amount int) Number {
|
2021-08-21 17:18:57 +03:00
|
|
|
c := Number{}
|
2023-07-20 02:33:07 +03:00
|
|
|
#c.value = a.val.value << BigInt(+amount)
|
2021-08-21 17:18:57 +03:00
|
|
|
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2023-07-20 02:33:07 +03:00
|
|
|
pub fn (a &Number) right_shift(amount int) Number {
|
2021-08-21 17:18:57 +03:00
|
|
|
c := Number{}
|
2023-07-20 02:33:07 +03:00
|
|
|
#c.value = a.val.value << BigInt(+amount)
|
2021-08-21 17:18:57 +03:00
|
|
|
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn (a &Number) clone() Number {
|
|
|
|
b := Number{}
|
|
|
|
#b.value = a.val.value
|
|
|
|
|
|
|
|
return b
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn factorial(nn &Number) Number {
|
|
|
|
mut n := nn.clone()
|
|
|
|
mut a := nn.clone()
|
|
|
|
n.dec()
|
|
|
|
mut i := 1
|
|
|
|
for !n.is_zero() {
|
|
|
|
res := a * n
|
|
|
|
n.dec()
|
|
|
|
a = res
|
|
|
|
i++
|
|
|
|
}
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
|
2023-07-20 02:33:07 +03:00
|
|
|
[deprecated: 'use factorial_int instead']
|
2021-08-21 17:18:57 +03:00
|
|
|
pub fn fact(n int) Number {
|
2023-07-20 02:33:07 +03:00
|
|
|
return factorial_int(n)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn factorial_int(n int) Number {
|
2021-08-21 17:18:57 +03:00
|
|
|
return factorial(from_int(n))
|
|
|
|
}
|