Splits 0 ≤ a < Q into a0 and a1 with a = a1*2^D + a0 and -2^(D-1) < a0 ≤ 2^(D-1). Returns a0 + Q and a1. FIPS 204: Power2Round (Algorithm 19)
fn power2Round(a: u32) struct
fn power2Round(a: u32) struct { a0_plus_q: u32, a1: u32 } {
// We effectively compute a0 = a mod± 2^D
// and a1 = (a - a0) / 2^D
var a0 = a & ((1 << D) - 1); // a mod 2^D
// a0 is one of 0, 1, ..., 2^(D-1)-1, 2^(D-1), 2^(D-1)+1, ..., 2^D-1
a0 -%= (1 << (D - 1)) + 1;
// now a0 is -2^(D-1)-1, -2^(D-1), ..., -2, -1, 0, ..., 2^(D-1)-2
// Next, add 2^D to those a0 that are negative (seen as i32)
a0 +%= @as(u32, @bitCast(@as(i32, @bitCast(a0)) >> 31)) & (1 << D);
// now a0 is 2^(D-1)-1, 2^(D-1), ..., 2^D-2, 2^D-1, 0, ..., 2^(D-1)-2
a0 -%= (1 << (D - 1)) - 1;
// now a0 is 0, 1, 2, ..., 2^(D-1)-1, 2^(D-1), -2^(D-1)+1, ..., -1
const a0_plus_q = Q +% a0;
const a1 = (a -% a0) >> D;
return .{ .a0_plus_q = a0_plus_q, .a1 = a1 };
}