blob: 4f0d8e43946f858205531fa50e39970433884e11 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
{-# 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
|