10 Suffixes like _a, _c mean that certain properties of some
11 object are required. Given an argument that doesn't satisfy
12 those properties, all bets are off.
15 /* Compute a + a + ... + a, for @a with an associative, commutative "+" */
16 generic gpow_ac : (a : @a, n : Z# -> @a) :: disposable @a, group_struct @a
18 /* Compute a · a · ... · a, for @a with an associative, commutative "·" */
19 generic fpow_ac : (a : @a, n : Z# -> std.result(@a, byte[:])) :: disposable @a, field_struct @a, ring_struct @a
22 generic gpow_ac = {a, n
23 var nb : std.bigint# = std.bigdup((n : std.bigint#))
24 var then_negate : bool = false
29 elif std.bigeqi(nb, 1)
32 elif std.bigeqi(nb, 2)
36 then_negate = nb.sign < 0
41 var double : @a = t.dup(a)
43 while !std.bigiszero(nb)
48 gadd_ip(double, double)
53 __dispose__(double) // TODO: recognize "disposable" trait
61 generic fpow_ac = {a, n
62 var nb : std.bigint# = std.bigdup((n : std.bigint#))
63 var then_invert : bool = false
68 elif std.bigeqi(nb, 1)
71 elif std.bigeqi(nb, 2)
75 then_invert = nb.sign < 0
80 var double : @a = t.dup(a)
82 while !std.bigiszero(nb)
87 rmul_ip(double, double)
92 __dispose__(double) // TODO: recognize "disposable" trait
99 | `std.None: -> `std.Err std.fmt("cannot invert {}^{} = {}", a, n, res)