-
Notifications
You must be signed in to change notification settings - Fork 15
/
UInt32.x
230 lines (181 loc) · 5.56 KB
/
UInt32.x
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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
const UInt32
extends UIntNumber
default(0) {
// ----- constants -----------------------------------------------------------------------------
/**
* The minimum value for an UInt32.
*/
static IntLiteral MinValue = 0;
/**
* The maximum value for an UInt32.
*/
static IntLiteral MaxValue = 0xFFFFFFFF;
// ----- Numeric funky interface ---------------------------------------------------------------
@Override
static conditional Int fixedBitLength() {
return True, 32;
}
@Override
static UInt32 zero() {
return 0;
}
@Override
static UInt32 one() {
return 1;
}
@Override
static conditional Range<UInt32> range() {
return True, MinValue..MaxValue;
}
// ----- constructors --------------------------------------------------------------------------
/**
* Construct a 32-bit unsigned integer number from its bitwise machine representation.
*
* @param bits an array of bit values that represent this number, ordered from left-to-right,
* Most Significant Bit (MSB) to Least Significant Bit (LSB)
*/
@Override
construct(Bit[] bits) {
assert bits.size == 32;
super(bits);
}
/**
* Construct a 32-bit unsigned integer number from its network-portable representation.
*
* @param bytes an array of byte values that represent this number, ordered from left-to-right,
* as they would appear on the wire or in a file
*/
@Override
construct(Byte[] bytes) {
assert bytes.size == 4;
super(bytes);
}
/**
* Construct a 32-bit unsigned integer number from its `String` representation.
*
* @param text an integer number, in text format
*/
@Override
construct(String text) {
construct UInt32(new IntLiteral(text).toUInt32().bits);
}
// ----- properties ----------------------------------------------------------------------------
@Override
Signum sign.get() {
return this == 0 ? Zero : Positive;
}
// ----- operations ----------------------------------------------------------------------------
@Override
@Op("+")
UInt32 add(UInt32! n) {
return this + n;
}
@Override
@Op("-")
UInt32 sub(UInt32! n) {
return this - n;
}
@Override
@Op("*")
UInt32 mul(UInt32! n) {
return this * n;
}
@Override
@Op("/")
UInt32 div(UInt32! n) {
return this / n;
}
@Override
@Op("%")
UInt32 mod(UInt32! n) {
return this % n;
}
@Override
UInt32 pow(UInt32! n) {
UInt32 result = 1;
while (n-- > 0) {
result *= this;
}
return result;
}
// ----- Sequential interface ------------------------------------------------------------------
@Override
conditional UInt32 next() {
if (this < MaxValue) {
return True, this + 1;
}
return False;
}
@Override
conditional UInt32 prev() {
if (this > MinValue) {
return True, this - 1;
}
return False;
}
// ----- conversions ---------------------------------------------------------------------------
@Override
Int8 toInt8(Boolean checkBounds = False) {
assert:bounds !checkBounds || this <= Int8.MaxValue;
return new Int8(bits[bitLength-8 ..< bitLength]);
}
@Override
Int16 toInt16(Boolean checkBounds = False) {
assert:bounds !checkBounds || this <= Int16.MaxValue;
return new Int16(bits[bitLength-16 ..< bitLength]);
}
@Override
Int32 toInt32(Boolean checkBounds = False) {
assert:bounds !checkBounds || this <= Int32.MaxValue;
return new Int32(bits);
}
@Auto
@Override
Int64 toInt64(Boolean checkBounds = False) = new Int64(new Bit[64](i -> i < 64-bitLength ? 0 : bits[i]));
@Auto
@Override
Int128 toInt128(Boolean checkBounds = False) = new Int128(new Bit[128](i -> i < 128-bitLength ? 0 : bits[i]));
@Override
UInt8 toUInt8(Boolean checkBounds = False) {
assert:bounds !checkBounds || this <= UInt8.MaxValue;
return new UInt8(bits[bitLength-8 ..< bitLength]);
}
@Override
UInt16 toUInt16(Boolean checkBounds = False) {
assert:bounds !checkBounds || this <= UInt16.MaxValue;
return new UInt16(bits[bitLength-16 ..< bitLength]);
}
@Override
UInt32 toUInt32(Boolean checkBounds = False) = this;
@Auto
@Override
UInt64 toUInt64(Boolean checkBounds = False) = new UInt64(new Bit[64](i -> i < 64-bitLength ? 0 : bits[i]));
@Auto
@Override
UInt128 toUInt128(Boolean checkBounds = False) = new UInt128(new Bit[128](i -> i < 128-bitLength ? 0 : bits[i]));
// ----- Stringable implementation -------------------------------------------------------------
@Override
Int estimateStringLength() {
return calculateStringSize(this, sizeArray);
}
@Override
Appender<Char> appendTo(Appender<Char> buf) {
if (sign == Zero) {
buf.add('0');
} else {
(UInt32 left, UInt32 digit) = this /% 10;
if (left.sign != Zero) {
left.appendTo(buf);
}
buf.add(Digits[digit]);
}
return buf;
}
// MaxValue = 4_294_967_295 (10 digits)
private static UInt32[] sizeArray =
[
9, 99, 999, 9_999, 99_999, 999_999,
9_999_999, 99_999_999, 999_999_999,
4_294_967_295
];
}