pub fn decompose_weight(weight: u64) -> Vec<u64> {
if weight == 0 {
return vec![];
}
let mut bits = Vec::new();
let mut remaining = weight;
let mut bit_position = 0u32;
while remaining > 0 {
if remaining & 1 == 1 {
bits.push(1u64 << bit_position);
}
remaining >>= 1;
bit_position += 1;
}
if bits.len() <= 16 {
bits.resize(16, 0);
return bits;
}
let mut shares = vec![0u64; 16];
for (i, &value) in bits.iter().enumerate() {
shares[i % 16] += value;
}
shares
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_zero() {
assert_eq!(decompose_weight(0), Vec::<u64>::new());
}
#[test]
fn test_power_of_two() {
let shares = decompose_weight(1);
assert_eq!(shares.len(), 16);
assert_eq!(shares.iter().sum::<u64>(), 1);
}
#[test]
fn test_composite() {
let shares = decompose_weight(5);
assert_eq!(shares.len(), 16);
assert_eq!(shares.iter().sum::<u64>(), 5);
}
#[test]
fn test_sixteen_bits() {
let shares = decompose_weight(65535);
assert_eq!(shares.len(), 16);
assert_eq!(shares.iter().sum::<u64>(), 65535);
assert_eq!(shares, (0..16).map(|i| 1u64 << i).collect::<Vec<_>>());
}
#[test]
fn test_more_than_sixteen_bits() {
let shares = decompose_weight(131071);
assert_eq!(shares.len(), 16);
assert_eq!(shares.iter().sum::<u64>(), 131071);
assert_eq!(shares[0], 1 + 65536);
assert_eq!(shares[1], 2);
}
#[test]
fn test_voting_weight() {
let weight = 14_250_000_000u64;
let shares = decompose_weight(weight);
assert_eq!(shares.len(), 16);
assert_eq!(shares.iter().sum::<u64>(), weight);
}
#[test]
fn test_real_balance() {
let weight = 101_768_753u64;
let shares = decompose_weight(weight);
assert_eq!(shares.len(), 16);
assert_eq!(shares.iter().sum::<u64>(), weight);
assert!(shares.iter().all(|&s| s < (1u64 << 30)));
}
#[test]
fn test_large_value() {
let weight = u64::MAX;
let shares = decompose_weight(weight);
assert_eq!(shares.len(), 16);
assert_eq!(shares.iter().sum::<u64>(), weight);
}
}