-
Notifications
You must be signed in to change notification settings - Fork 2
/
tbitfield.cpp
199 lines (158 loc) · 4.43 KB
/
tbitfield.cpp
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// ÍÍÃÓ, ÂÌÊ, Êóðñ "Ìåòîäû ïðîãðàììèðîâàíèÿ-2", Ñ++, ÎÎÏ
//
// tbitfield.cpp - Copyright (c) Ãåðãåëü Â.Ï. 07.05.2001
// Ïåðåðàáîòàíî äëÿ Microsoft Visual Studio 2008 Ñûñîåâûì À.Â. (19.04.2015)
//
// Áèòîâîå ïîëå
#include "tbitfield.h"
TBitField::TBitField(int len)
{
if (len <= 0) throw "Create BitField with negative length!";
BitLen = len;
MemLen = BitLen / 8 + (BitLen % 8 ? 1 : 0);
pMem = new TELEM[MemLen];
for (int n = 0; n < MemLen; ++n)
pMem[n] = 0;
}
TBitField::TBitField(const TBitField &bf) // êîíñòðóêòîð êîïèðîâàíèÿ
{
BitLen = bf.BitLen;
MemLen = bf.MemLen;
pMem = new TELEM[MemLen];
for (int n = 0; n < MemLen; ++n)
pMem[n] = bf.pMem[n];
}
TBitField::~TBitField()
{
delete[] pMem;
}
int TBitField::GetMemIndex(const int n) const // èíäåêñ Ìåì äëÿ áèòà n
{
return n / 8;
}
TELEM TBitField::GetMemMask(const int n) const // áèòîâàÿ ìàñêà äëÿ áèòà n
{
return 1 << (n % 8);
}
// äîñòóï ê áèòàì áèòîâîãî ïîëÿ
int TBitField::GetLength(void) const // ïîëó÷èòü äëèíó (ê-âî áèòîâ)
{
return BitLen;
}
void TBitField::SetBit(const int n) // óñòàíîâèòü áèò
{
if (n < 0) throw "Set bit with negative index!";
else if (n >= BitLen) throw "Set bit with too large index!";
pMem[GetMemIndex(n)] |= GetMemMask(n);
}
void TBitField::ClrBit(const int n) // î÷èñòèòü áèò
{
if (n < 0) throw "Clear bit with negative index!";
else if (n >= BitLen) throw "Clear bit with too large index!";
pMem[GetMemIndex(n)] &= ~GetMemMask(n);
}
int TBitField::GetBit(const int n) const // ïîëó÷èòü çíà÷åíèå áèòà
{
if (n < 0) throw "Get bit with negative index!";
else if (n >= BitLen) throw "Get bit with too large index!";
return (pMem[GetMemIndex(n)] & GetMemMask(n)) >> (n % 8);
// Ïðèìåð, n = 3:
//
// 76543210 ¹ áèòà
//
// 01001010 pMem[GetMemIndex(n)]
// 00001000 GetMemMask(n)
//
// 00001000 pMem[GetMemIndex(n)] & GetMemMask(n)
//
// >>>00001000 (pMem[GetMemIndex(n)] & GetMemMask(n)) >> (n % 8)
// 00000001XXX
//
}
// áèòîâûå îïåðàöèè
TBitField& TBitField::operator=(const TBitField &bf) // ïðèñâàèâàíèå
{
TBitField tmp(bf);
tmp.BitLen = BitLen;
tmp.MemLen = MemLen;
BitLen = bf.BitLen;
MemLen = bf.MemLen;
TELEM *pMemTmp = pMem;
pMem = tmp.pMem;
tmp.pMem = pMemTmp;
return *this;
}
int TBitField::operator==(const TBitField &bf) const // ñðàâíåíèå
{
for (int i = 0; i < BitLen && i < bf.BitLen; ++i)
if (GetBit(i) != bf.GetBit(i)) return 0;
if (BitLen > bf.BitLen) {
for (int i = bf.BitLen; i < BitLen; ++i)
if (GetBit(i) != 0) return 0;
}
else if (bf.BitLen > BitLen) {
for (int i = BitLen; i < bf.BitLen; ++i)
if (bf.GetBit(i) != 0) return 0;
}
return 1;
}
int TBitField::operator!=(const TBitField &bf) const // ñðàâíåíèå
{
return !(*this == bf);
}
TBitField TBitField::operator|(const TBitField &bf) // îïåðàöèÿ "èëè"
{
TBitField result(BitLen > bf.BitLen ? BitLen : bf.BitLen);
for (int i = 0; i < BitLen && i < bf.BitLen; ++i)
if (GetBit(i) || bf.GetBit(i)) result.SetBit(i);
if (BitLen > bf.BitLen) {
for (int i = bf.BitLen; i < BitLen; ++i)
if (GetBit(i)) result.SetBit(i); else result.ClrBit(i);
}
else if (bf.BitLen > BitLen) {
for (int i = BitLen; i < bf.BitLen; ++i)
if (bf.GetBit(i)) result.SetBit(i); else result.ClrBit(i);
}
return result;
}
TBitField TBitField::operator&(const TBitField &bf) // îïåðàöèÿ "è"
{
TBitField result(BitLen > bf.BitLen ? BitLen : bf.BitLen);
for (int i = 0; i < BitLen && i < bf.BitLen; ++i)
if (GetBit(i) && bf.GetBit(i)) result.SetBit(i);
if (BitLen > bf.BitLen)
for (int i = bf.BitLen; i < BitLen; ++i) result.ClrBit(i);
else if (bf.BitLen > BitLen)
for (int i = BitLen; i < bf.BitLen; ++i) result.ClrBit(i);
return result;
}
TBitField TBitField::operator~(void) // îòðèöàíèå
{
TBitField result(BitLen);
for (int i = 0; i < result.BitLen; ++i)
if (GetBit(i)) result.ClrBit(i); else result.SetBit(i);
return result;
}
// ââîä/âûâîä
istream &operator>>(istream &istr, TBitField &bf) // ââîä
{
char ch;
istr.get(ch);
int n = 0;
while (!istr.eof()) {
switch (ch) {
case '1': bf.SetBit(n); break;
case '0': bf.ClrBit(n); break;
default: break;
}
++n;
istr.get(ch);
}
return istr;
}
ostream &operator<<(ostream &ostr, const TBitField &bf) // âûâîä
{
for (int n = 0; n < bf.BitLen; ++n)
ostr << bf.GetBit(n) ? '1' : '0';
return ostr;
}