2022-05-13 08:21:34 +03:00
|
|
|
import time
|
|
|
|
import math.big
|
|
|
|
|
|
|
|
const t = time.new_stopwatch()
|
|
|
|
|
|
|
|
// a := big.integer_from_i64(2).pow(123123123)
|
|
|
|
// println(a)
|
|
|
|
|
|
|
|
fn timed_println(msg string) {
|
|
|
|
timed_println_extended(t, msg)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn timed_println_extended(t time.StopWatch, msg string) {
|
2022-11-15 16:53:13 +03:00
|
|
|
println('${t.elapsed().microseconds():12} | ${msg}')
|
2022-05-13 08:21:34 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
fn f(x big.Integer, y int) big.Integer {
|
|
|
|
timed_println('f x y, y=${y:12}')
|
|
|
|
if y & 1 == 0 {
|
|
|
|
return f(x * x, y / 2)
|
|
|
|
}
|
|
|
|
if y == 1 {
|
|
|
|
return x
|
|
|
|
}
|
|
|
|
return g(x * x, y / 2, x)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn g(x big.Integer, y int, z big.Integer) big.Integer {
|
|
|
|
timed_println('g x y z, y=${y:12}')
|
|
|
|
if y & 1 == 0 {
|
|
|
|
return g(x * x, y / 2, z)
|
|
|
|
}
|
|
|
|
if y == 1 {
|
|
|
|
return x * z
|
|
|
|
}
|
|
|
|
return g(x * x, y / 2, x * z)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn calculate_and_measure(calc_label string, cb fn () big.Integer) string {
|
|
|
|
sw := time.new_stopwatch()
|
|
|
|
timed_println_extended(sw, 'start')
|
|
|
|
a := cb()
|
2022-11-15 16:53:13 +03:00
|
|
|
timed_println_extended(sw, 'done ${calc_label}')
|
2022-05-13 08:21:34 +03:00
|
|
|
timed_println_extended(sw, 'a.bit_len(): ${a.bit_len():12}')
|
|
|
|
|
|
|
|
timed_println_extended(sw, 'before a.str()')
|
|
|
|
// s := a.hex() // hex is very fast since it does not need to do divisions at all
|
|
|
|
s := a.str()
|
|
|
|
timed_println_extended(sw, 'after a.str()')
|
|
|
|
dump(s.len)
|
|
|
|
dump(s#[0..10])
|
|
|
|
dump(s#[-10..])
|
|
|
|
timed_println_extended(sw, 'finish')
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
fn test_exponentiation() {
|
|
|
|
res1 := calculate_and_measure('f(x, y)', fn () big.Integer {
|
|
|
|
return f(big.integer_from_int(2), 66777)
|
|
|
|
})
|
|
|
|
res2 := calculate_and_measure('big.int(x).pow(y)', fn () big.Integer {
|
|
|
|
return big.integer_from_i64(2).pow(66777)
|
|
|
|
})
|
|
|
|
assert res1 == res2
|
|
|
|
}
|