///|
/// Integer log base 2 (floor). Returns 0 for input 0.
fn ilog(x : Int) -> Int {
  let mut val = x
  let mut count = 0
  while val > 0 {
    count = count + 1
    val = val >> 1
  }
  count
}

///|
/// Bit-reverse an n-bit integer.
fn bit_reverse(x : Int, bits : Int) -> Int {
  let mut result = 0
  let mut val = x
  for _ in 0..> 1
  }
  result
}

///|
/// Compute float32 from Vorbis packed representation.
/// Vorbis uses a custom float format: 1 sign bit, 5 exponent bits, 21 mantissa bits.
fn float32_unpack(x : Int) -> Float {
  let mantissa = x & 0x1FFFFF
  let sign = x & 0x80000000
  let exponent = (x & 0x7FE00000) >> 21
  let signed_mantissa : Float = if sign != 0 {
    -Float::from_int(mantissa)
  } else {
    Float::from_int(mantissa)
  }
  let exp_val = Float::from_int(exponent - 788)
  signed_mantissa * pow2f(exp_val)
}

///|
/// Compute 2^x for float exponent using repeated squaring.
fn pow2f(x : Float) -> Float {
  // 2^x = exp(x * ln(2))
  let ln2 : Float = 0.6931472
  let v = x * ln2
  // Use Taylor series for exp(v) with reasonable precision
  let mut result : Float = 1.0
  let mut term : Float = 1.0
  for i in 1..<=20 {
    term = term * v / Float::from_int(i)
    result = result + term
  }
  result
}

///|
test "ilog basic values" {
  assert_eq(ilog(0), 0)
  assert_eq(ilog(1), 1)
  assert_eq(ilog(2), 2)
  assert_eq(ilog(3), 2)
  assert_eq(ilog(4), 3)
  assert_eq(ilog(255), 8)
  assert_eq(ilog(256), 9)
}

///|
test "bit_reverse" {
  assert_eq(bit_reverse(0b1010, 4), 0b0101)
  assert_eq(bit_reverse(0b1100, 4), 0b0011)
  assert_eq(bit_reverse(0b1, 8), 0b10000000)
  assert_eq(bit_reverse(0, 4), 0)
}

///|
test "float32_unpack basic" {
  // Simple test: value 0 should give 0
  let result = float32_unpack(0)
  assert_true(result < 0.001 && result > -0.001)
}

///|
test "lookup1_values" {
  assert_eq(ilog(15), 4)
  assert_eq(ilog(16), 5)
  assert_eq(ilog(1023), 10)
  assert_eq(ilog(1024), 11)
}