content: {-# LANGUAGE BangPatterns, MagicHash #-}
  module Main where
  
  import Data.Bits (finiteBitSize)
  import GHC.Exts
  
  main :: IO ()
  main = do
    -- 0 is the annihilator of andI#
    print (I# (maxI# `andI#`    0#) == 0)
    print (I# (minI# `andI#`    0#) == 0)
    print (I# (0#    `andI#` maxI#) == 0)
    print (I# (0#    `andI#` minI#) == 0)
    print (I# (0#    `andI#`    0#) == 0)
    -- integer with all bits set to 1 is the neutral element of orI#,
    -- in two's complement this is -1
    print (I# (maxI# `andI#`   -1#) == maxI)
    print (I# (minI# `andI#`   -1#) == minI)
    print (I# (-1#   `andI#` maxI#) == maxI)
    print (I# (-1#   `andI#` minI#) == minI)
    print (I# (-1#   `andI#`   -1#) == -1)
    -- these two numbers have every other bit set, they should give 0
    print (I# (magicInt1# `andI#` magicInt2#) == 0)
  
    -- integer with all bits set to 1 is the annihilator of orI#,
    print (I# (maxI# `orI#`    -1#) == -1)
    print (I# (minI# `orI#`    -1#) == -1)
    print (I# (-1#   `orI#`  maxI#) == -1)
    print (I# (-1#   `orI#`  minI#) == -1)
    print (I# (-1#   `orI#`    -1#) == -1)
    -- 0 is the neutral element of orI#
    print (I# (maxI# `orI#`     0#) == maxI)
    print (I# (minI# `orI#`     0#) == minI)
    print (I# (0#    `orI#`  maxI#) == maxI)
    print (I# (0#    `orI#`  minI#) == minI)
    print (I# (0#    `orI#`     0#) == 0)
    -- this time we should get an integer with all bits set, that is -1
    print (I# (magicInt1# `orI#` magicInt2#) == -1)
  
    -- suprising as the first two tests may look, this is what we expect from
    -- bitwise negation in two's complement enccoding
    print (I# (notI#  0#) == -1)
    print (I# (notI# -1#) ==  0)
    -- magic int numbers are bitwise complementary
    print (I# (notI# magicInt1#) == magicInt2)
    print (I# (notI# magicInt2#) == magicInt1)
  
    -- 0 is the identity of xor
    print (I# (minI# `xorI#`    0#) == minI)
    print (I# (maxI# `xorI#`    0#) == maxI)
    print (I# (0#    `xorI#` minI#) == minI)
    print (I# (0#    `xorI#` maxI#) == maxI)
    -- anything xored with itself is 0
    print (I# (maxI# `xorI#` maxI#) == 0)
    print (I# (minI# `xorI#` minI#) == 0)
    -- xoring with -1 is like bitwise negation (becuse -1 has all bits set to 1)
    print (I# (minI# `xorI#`   -1#) == maxI)
    print (I# (maxI# `xorI#`   -1#) == minI)
    print (I# (-1#   `xorI#` minI#) == maxI)
    print (I# (-1#   `xorI#` maxI#) == minI)
    -- since these two have exactly the opposite bits turned on they should
    -- give an int with all bits set, and that is -1 as you probably already
    -- remember by now
    print (I# (magicInt1# `xorI#` magicInt2#) == -1)
      where
        intBitSize = finiteBitSize (undefined :: Int)
        minI  = minBound :: Int
        maxI  = maxBound :: Int
        minI# = x
            where !(I# x) = minBound
        maxI# = x
            where !(I# x) = maxBound
        magicInt1 = sum $ map (2^) [0,2..intBitSize] :: Int
        magicInt2 = sum $ map (2^) [1,3..intBitSize] :: Int
        magicInt1# = x
            where !(I# x) = magicInt1
        magicInt2# = x
            where !(I# x) = magicInt2
  