(defsuite
  "bitwise-operations"
  (deftest
    "bitwise-and basic"
    (do
      (assert= 0 (bitwise-and 0 0))
      (assert= 1 (bitwise-and 3 1))
      (assert= 0 (bitwise-and 5 2))
      (assert= 4 (bitwise-and 12 6))))
  (deftest
    "bitwise-and identity and zero"
    (do
      (assert= 255 (bitwise-and 255 255))
      (assert= 0 (bitwise-and 255 0))))
  (deftest
    "bitwise-or basic"
    (do
      (assert= 0 (bitwise-or 0 0))
      (assert= 3 (bitwise-or 1 2))
      (assert= 7 (bitwise-or 5 3))
      (assert= 15 (bitwise-or 9 6))))
  (deftest
    "bitwise-or identity"
    (do
      (assert= 255 (bitwise-or 255 0))
      (assert= 255 (bitwise-or 0 255))))
  (deftest
    "bitwise-xor basic"
    (do
      (assert= 0 (bitwise-xor 0 0))
      (assert= 3 (bitwise-xor 1 2))
      (assert= 6 (bitwise-xor 3 5))
      (assert= 0 (bitwise-xor 255 255))))
  (deftest
    "bitwise-xor toggle bits"
    (do
      (assert= 14 (bitwise-xor 10 4))
      (assert= 10 (bitwise-xor 14 4))))
  (deftest
    "bitwise-not zero"
    (do (assert= -1 (bitwise-not 0))))
  (deftest
    "bitwise-not positive"
    (do
      (assert= -2 (bitwise-not 1))
      (assert= -5 (bitwise-not 4))
      (assert= -256 (bitwise-not 255))))
  (deftest
    "bitwise-not negative"
    (do
      (assert= 0 (bitwise-not -1))
      (assert= 1 (bitwise-not -2))
      (assert= 4 (bitwise-not -5))))
  (deftest
    "bitwise-not double negation"
    (do
      (assert= 42 (bitwise-not (bitwise-not 42)))
      (assert= 0 (bitwise-not (bitwise-not 0)))))
  (deftest
    "arithmetic-shift left"
    (do
      (assert= 2 (arithmetic-shift 1 1))
      (assert= 4 (arithmetic-shift 1 2))
      (assert= 16 (arithmetic-shift 1 4))
      (assert= 8 (arithmetic-shift 2 2))))
  (deftest
    "arithmetic-shift right"
    (do
      (assert= 1 (arithmetic-shift 2 -1))
      (assert= 1 (arithmetic-shift 4 -2))
      (assert= 5 (arithmetic-shift 10 -1))
      (assert= 2 (arithmetic-shift 16 -3))))
  (deftest
    "arithmetic-shift by zero"
    (do
      (assert= 42 (arithmetic-shift 42 0))
      (assert= 0 (arithmetic-shift 0 5))))
  (deftest
    "arithmetic-shift negative value right preserves sign"
    (do
      (assert= -1 (arithmetic-shift -1 -1))
      (assert= -2 (arithmetic-shift -4 -1))))
  (deftest
    "bit-count zero"
    (do (assert= 0 (bit-count 0))))
  (deftest
    "bit-count powers of two"
    (do
      (assert= 1 (bit-count 1))
      (assert= 1 (bit-count 2))
      (assert= 1 (bit-count 4))
      (assert= 1 (bit-count 128))))
  (deftest
    "bit-count all-ones values"
    (do
      (assert= 8 (bit-count 255))
      (assert= 4 (bit-count 15))
      (assert= 2 (bit-count 3))))
  (deftest
    "bit-count mixed"
    (do
      (assert= 3 (bit-count 7))
      (assert= 2 (bit-count 5))
      (assert= 3 (bit-count 11))
      (assert= 4 (bit-count 30))))
  (deftest
    "integer-length zero"
    (do (assert= 0 (integer-length 0))))
  (deftest
    "integer-length powers of two"
    (do
      (assert= 1 (integer-length 1))
      (assert= 2 (integer-length 2))
      (assert= 3 (integer-length 4))
      (assert= 4 (integer-length 8))
      (assert= 8 (integer-length 128))))
  (deftest
    "integer-length non-powers"
    (do
      (assert= 2 (integer-length 3))
      (assert= 3 (integer-length 5))
      (assert= 3 (integer-length 7))
      (assert= 8 (integer-length 255))
      (assert= 9 (integer-length 256))))
  (deftest
    "bitwise ops compose"
    (do
      (assert=
        5
        (bitwise-and
          (bitwise-or 5 3)
          (bitwise-xor 7 2)))
      (assert= 0 (bitwise-and 170 85))))
  (deftest
    "arithmetic-shift round-trip"
    (do
      (assert=
        10
        (arithmetic-shift (arithmetic-shift 10 3) -3))))
  (deftest
    "extract bits with mask"
    (do
      (let
        ((x 52))
        (assert=
          5
          (bitwise-and (arithmetic-shift x -2) 7)))))
  (deftest
    "clear low bits with bitwise-not mask"
    (do
      (assert= 252 (bitwise-and 255 (bitwise-not 3)))))
  (deftest
    "integer-length after shift"
    (do
      (assert=
        4
        (integer-length (arithmetic-shift 1 3))))))