Repository navigation
Expand file tree
/
Copy pathbits.cm
More file actions
120 lines (91 loc) · 4.86 KB
/
Copy pathbits.cm
File metadata and controls
120 lines (91 loc) · 4.86 KB
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
##
Working on the bits of a whole number.
Everything here is spelled as a word. '&' and '|' would have been new punctuation, and '|'
was not available in any case: it already writes a fraction. Every operation on bits says
'bitwise', because 'and', 'or', and 'exclusive or' each mean something on their own. The
two shifts claim words nothing else uses, so they stand alone.
##
shared model Program
##
@summary: A row of switches, each standing for one thing that is on or off.
@remarks: Written in binary, the value and the picture are the same thing.
##
constant integer Read = 0b0001;
constant integer Write = 0b0010;
constant integer Delete = 0b0100;
constant integer Share = 0b1000;
function Main()
Program.CombiningAndAsking();
Program.TheThreeOperations();
Program.Shifting();
end function
##
@summary: Putting flags together and asking what is set.
@remarks: 'bitwise or' combines them — a bit is on in the answer if it was on in
either. 'bitwise and' asks whether one is present, since the answer keeps only the
bits both sides had.
##
function CombiningAndAsking()
Console.WriteLine("== putting flags together and asking about them ==");
integer granted = Program.Read bitwise or Program.Write;
Console.WriteLine(" granted: " + granted.Format("B"));
Console.WriteLine(" may read: " + ((granted bitwise and Program.Read) != 0));
Console.WriteLine(" may delete: " + ((granted bitwise and Program.Delete) != 0));
# Adding one that is already there changes nothing, which is what makes 'or' safe to
# apply twice.
integer again = granted bitwise or Program.Read;
Console.WriteLine(" added twice: " + (again == granted));
# And adding one that is not there sets it, which is the other half of the same rule.
integer widened = granted bitwise or Program.Share;
Console.WriteLine(" now shares: " + ((widened bitwise and Program.Share) != 0));
end function
##
@summary: Exclusive or, which is its own undo.
@remarks: All three operations on bits are written with 'bitwise' in front, because
'and', 'or', and 'exclusive or' each name a boolean operation on their own. On
booleans there is nothing this one does that '!=' does not already say. Applying the
same mask twice gives back what it started with.
##
function TheThreeOperations()
Console.WriteLine("== and, or, exclusive or ==");
integer left = 0b1100;
integer right = 0b1010;
Console.WriteLine(" 1100 bitwise and 1010: "
+ (left bitwise and right).Format("B"));
Console.WriteLine(" 1100 bitwise or 1010: "
+ (left bitwise or right).Format("B"));
Console.WriteLine(" 1100 bitwise exclusive or 1010: "
+ (left bitwise exclusive or right).Format("B"));
Console.WriteLine(" a second pass undoes it: "
+ ((left bitwise exclusive or right
bitwise exclusive or right) == left));
##
The three sit on three levels, as they do in C#: 'bitwise or' is loosest, then
'bitwise exclusive or', then 'bitwise and'. So the line below is
1100 or (0011 and 0001), which is 1101.
##
Console.WriteLine(" levels: "
+ (0b1100 bitwise or 0b0011 bitwise and 0b0001).Format("B"));
end function
##
@summary: Moving every bit along, which doubles or halves the number.
@remarks: The direction is in the word rather than in the sign of the amount, so there
is nothing to work out.
An amount below zero or past 63 is refused: an integer holds 64 bits, and a shift
further than that has nothing left to move. C# wraps the amount instead and reports
nothing, which is a result the line does not suggest.
##
function Shifting()
Console.WriteLine("== moving the bits along ==");
integer one = 0b0001;
Console.WriteLine(" 1 left 4: " + (one shiftleft 4).Format("B"));
Console.WriteLine(" and as a number: " + (one shiftleft 4));
integer sixty4 = 0b1000000;
Console.WriteLine(" 64 right 3: " + (sixty4 shiftright 3).Format("B"));
# Shifting left by one doubles, which is the same arithmetic said another way.
Console.WriteLine(" doubling: " + ((5 shiftleft 1) == 5 * 2));
# A shift binds tighter than a comparison and looser than arithmetic, so the amount
# here is 2 + 1 and the whole thing is compared afterwards.
Console.WriteLine(" precedence: " + ((1 shiftleft 2 + 1) == 8));
end function
end model