v/vlib/math/big/large_number_power_and_stri...

66 lines
1.5 KiB
V

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) {
println('${t.elapsed().microseconds():12} | $msg')
}
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()
timed_println_extended(sw, 'done $calc_label')
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
}