1const builtin = @import("builtin");
2const std = @import("std");
3const assert = std.debug.assert;
4const expect = std.testing.expect;
5const expectEqual = std.testing.expectEqual;
6const expectEqualSlices = std.testing.expectEqualSlices;
7const maxInt = std.math.maxInt;
8const minInt = std.math.minInt;
9const mem = std.mem;
10const math = std.math;
11
12test "assignment operators" {
13 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
14 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
15 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
16
17 var i: u32 = 0;
18 i += 5;
19 try expect(i == 5);
20 i -= 2;
21 try expect(i == 3);
22 i *= 20;
23 try expect(i == 60);
24 i /= 3;
25 try expect(i == 20);
26 i %= 11;
27 try expect(i == 9);
28 i <<= 1;
29 try expect(i == 18);
30 i >>= 2;
31 try expect(i == 4);
32 i = 6;
33 i &= 5;
34 try expect(i == 4);
35 i ^= 6;
36 try expect(i == 2);
37 i = 6;
38 i |= 3;
39 try expect(i == 7);
40}
41
42test "three expr in a row" {
43 try testThreeExprInARow(false, true);
44 try comptime testThreeExprInARow(false, true);
45}
46fn testThreeExprInARow(f: bool, t: bool) !void {
47 try assertFalse(f or f or f);
48 try assertFalse(t and t and f);
49 try assertFalse(1 | 2 | 4 != 7);
50 try assertFalse(3 ^ 6 ^ 8 != 13);
51 try assertFalse(7 & 14 & 28 != 4);
52 try assertFalse(9 << 1 << 2 != 9 << 3);
53 try assertFalse(90 >> 1 >> 2 != 90 >> 3);
54 try assertFalse(100 - 1 + 1000 != 1099);
55 try assertFalse(5 * 4 / 2 % 3 != 1);
56 try assertFalse(@as(i32, @as(i32, 5)) != 5);
57 try assertFalse(!!false);
58 try assertFalse(@as(i32, 7) != --(@as(i32, 7)));
59}
60fn assertFalse(b: bool) !void {
61 try expect(!b);
62}
63
64test "@clz small" {
65 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
66 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
67 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
68 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
69
70 try testClzSmall();
71 try comptime testClzSmall();
72}
73
74fn testClzSmall() !void {
75 try expect(testOneClz(u8, 0b10001010) == 0);
76 try expect(testOneClz(u8, 0b00001010) == 4);
77 try expect(testOneClz(u8, 0b00011010) == 3);
78 try expect(testOneClz(u8, 0b00000000) == 8);
79 try expect(testOneClz(i8, -1) == 0);
80}
81
82test "@clz big ints" {
83 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
84 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
85 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
86 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
87
88 try testClzBigInts();
89 try comptime testClzBigInts();
90}
91
92fn testClzBigInts() !void {
93 try expect(testOneClz(u128, 0xffffffffffffffff) == 64);
94 try expect(testOneClz(u128, 0x10000000000000000) == 63);
95}
96
97fn testOneClz(comptime T: type, x: T) u32 {
98 return @clz(x);
99}
100
101test "@clz vectors" {
102 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
103 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
104 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
105 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
106 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
107
108 try testClzVectors();
109 try comptime testClzVectors();
110}
111
112fn testClzVectors() !void {
113 const Vu4 = @Vector(64, u4);
114 const Vu8 = @Vector(64, u8);
115 const Vu128 = @Vector(64, u128);
116
117 @setEvalBranchQuota(10_000);
118 try testOneClzVector(u8, 64, @as(Vu8, @splat(0b10001010)), @as(Vu4, @splat(0)));
119 try testOneClzVector(u8, 64, @as(Vu8, @splat(0b00001010)), @as(Vu4, @splat(4)));
120 try testOneClzVector(u8, 64, @as(Vu8, @splat(0b00011010)), @as(Vu4, @splat(3)));
121 try testOneClzVector(u8, 64, @as(Vu8, @splat(0b00000000)), @as(Vu4, @splat(8)));
122 try testOneClzVector(u128, 64, @as(Vu128, @splat(0xffffffffffffffff)), @as(Vu8, @splat(64)));
123 try testOneClzVector(u128, 64, @as(Vu128, @splat(0x10000000000000000)), @as(Vu8, @splat(63)));
124}
125
126fn testOneClzVector(
127 comptime T: type,
128 comptime len: u32,
129 x: @Vector(len, T),
130 expected: @Vector(len, u32),
131) !void {
132 try expectVectorsEqual(@clz(x), expected);
133}
134
135fn expectVectorsEqual(a: anytype, b: anytype) !void {
136 const len_a = @typeInfo(@TypeOf(a)).vector.len;
137 const len_b = @typeInfo(@TypeOf(b)).vector.len;
138 try expect(len_a == len_b);
139 try expect(@reduce(.And, a == b));
140}
141
142test "@ctz small" {
143 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
144 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
145 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
146 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
147
148 try testCtzSmall();
149 try comptime testCtzSmall();
150}
151
152fn testCtzSmall() !void {
153 try expect(testOneCtz(u8, 0b10100000) == 5);
154 try expect(testOneCtz(u8, 0b10001010) == 1);
155 try expect(testOneCtz(u8, 0b00000000) == 8);
156 try expect(testOneCtz(i8, -1) == 0);
157 try expect(testOneCtz(i8, -2) == 1);
158 try expect(testOneCtz(u16, 0b00000000) == 16);
159}
160
161fn testOneCtz(comptime T: type, x: T) u32 {
162 return @ctz(x);
163}
164
165test "@ctz 128-bit integers" {
166 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
167 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
168 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
169 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
170
171 try testCtz128();
172 try comptime testCtz128();
173}
174
175fn testCtz128() !void {
176 try expect(testOneCtz(u128, @as(u128, 0x40000000000000000000000000000000)) == 126);
177 try expect(math.rotl(u128, @as(u128, 0x40000000000000000000000000000000), @as(u8, 1)) == @as(u128, 0x80000000000000000000000000000000));
178 try expect(testOneCtz(u128, @as(u128, 0x80000000000000000000000000000000)) == 127);
179 try expect(testOneCtz(u128, math.rotl(u128, @as(u128, 0x40000000000000000000000000000000), @as(u8, 1))) == 127);
180}
181
182test "@ctz vectors" {
183 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
184 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
185 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
186 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
187 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
188
189 try testCtzVectors();
190 try comptime testCtzVectors();
191}
192
193fn testCtzVectors() !void {
194 const Vu4 = @Vector(64, u4);
195 const Vu8 = @Vector(64, u8);
196 @setEvalBranchQuota(10_000);
197 try testOneCtzVector(u8, 64, @as(Vu8, @splat(0b10100000)), @as(Vu4, @splat(5)));
198 try testOneCtzVector(u8, 64, @as(Vu8, @splat(0b10001010)), @as(Vu4, @splat(1)));
199 try testOneCtzVector(u8, 64, @as(Vu8, @splat(0b00000000)), @as(Vu4, @splat(8)));
200 try testOneCtzVector(u16, 64, @as(@Vector(64, u16), @splat(0b00000000)), @as(@Vector(64, u5), @splat(16)));
201}
202
203fn testOneCtzVector(
204 comptime T: type,
205 comptime len: u32,
206 x: @Vector(len, T),
207 expected: @Vector(len, u32),
208) !void {
209 try expectVectorsEqual(@ctz(x), expected);
210}
211
212test "const number literal" {
213 const one = 1;
214 const eleven = ten + one;
215
216 try expect(eleven == 11);
217}
218const ten = 10;
219
220test "float equality" {
221 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
222 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
223
224 const x: f64 = 0.012;
225 const y: f64 = x + 1.0;
226
227 try testFloatEqualityImpl(x, y);
228 try comptime testFloatEqualityImpl(x, y);
229}
230
231fn testFloatEqualityImpl(x: f64, y: f64) !void {
232 const y2 = x + 1.0;
233 try expect(y == y2);
234}
235
236test "hex float literal parsing" {
237 comptime assert(0x1.0 == 1.0);
238}
239
240test "hex float literal within range" {
241 const a = 0x1.0p16383;
242 const b = 0x0.1p16387;
243 const c = 0x1.0p-16382;
244 _ = a;
245 _ = b;
246 _ = c;
247}
248
249test "quad hex float literal parsing in range" {
250 const a = 0x1.af23456789bbaaab347645365cdep+5;
251 const b = 0x1.dedafcff354b6ae9758763545432p-9;
252 const c = 0x1.2f34dd5f437e849b4baab754cdefp+4534;
253 const d = 0x1.edcbff8ad76ab5bf46463233214fp-435;
254 _ = a;
255 _ = b;
256 _ = c;
257 _ = d;
258}
259
260test "underscore separator parsing" {
261 try expect(1_234_567 == 1234567);
262 try expect(1_234_567 == 1234567);
263 try expect(1_2_3_4_5_6_7 == 1234567);
264
265 try expect(0b0_0_0_0 == 0);
266 try expect(0b1010_1010 == 0b10101010);
267 try expect(0b0000_1010_1010 == 0b10101010);
268 try expect(0b1_0_1_0_1_0_1_0 == 0b10101010);
269
270 try expect(0o0_0_0_0 == 0);
271 try expect(0o1010_1010 == 0o10101010);
272 try expect(0o0000_1010_1010 == 0o10101010);
273 try expect(0o1_0_1_0_1_0_1_0 == 0o10101010);
274
275 try expect(0x0_0_0_0 == 0);
276 try expect(0x1010_1010 == 0x10101010);
277 try expect(0x0000_1010_1010 == 0x10101010);
278 try expect(0x1_0_1_0_1_0_1_0 == 0x10101010);
279
280 try expect(123_456.789_000e1_0 == 123456.789000e10);
281 try expect(1_2_3_4_5_6.7_8_9_0_0_0e0_0_1_0 == 123456.789000e10);
282
283 try expect(0x1234_5678.9ABC_DEF0p-1_0 == 0x12345678.9ABCDEF0p-10);
284 try expect(0x1_2_3_4_5_6_7_8.9_A_B_C_D_E_F_0p-0_0_0_1_0 == 0x12345678.9ABCDEF0p-10);
285}
286
287test "comptime_int addition" {
288 comptime {
289 try expect(35361831660712422535336160538497375248 + 101752735581729509668353361206450473702 == 137114567242441932203689521744947848950);
290 try expect(594491908217841670578297176641415611445982232488944558774612 + 390603545391089362063884922208143568023166603618446395589768 == 985095453608931032642182098849559179469148836107390954364380);
291 }
292}
293
294test "comptime_int multiplication" {
295 comptime {
296 try expect(
297 45960427431263824329884196484953148229 * 128339149605334697009938835852565949723 == 5898522172026096622534201617172456926982464453350084962781392314016180490567,
298 );
299 try expect(
300 594491908217841670578297176641415611445982232488944558774612 * 390603545391089362063884922208143568023166603618446395589768 == 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016,
301 );
302 }
303}
304
305test "comptime_int shifting" {
306 comptime {
307 try expect((@as(u128, 1) << 127) == 0x80000000000000000000000000000000);
308 }
309}
310
311test "comptime_int multi-limb shift and mask" {
312 comptime {
313 var a = 0xefffffffa0000001eeeeeeefaaaaaaab;
314
315 try expect(@as(u32, a & 0xffffffff) == 0xaaaaaaab);
316 a >>= 32;
317 try expect(@as(u32, a & 0xffffffff) == 0xeeeeeeef);
318 a >>= 32;
319 try expect(@as(u32, a & 0xffffffff) == 0xa0000001);
320 a >>= 32;
321 try expect(@as(u32, a & 0xffffffff) == 0xefffffff);
322 a >>= 32;
323
324 try expect(a == 0);
325 }
326}
327
328test "comptime_int multi-limb partial shift right" {
329 comptime {
330 var a = 0x1ffffffffeeeeeeee;
331 a >>= 16;
332 try expect(a == 0x1ffffffffeeee);
333 }
334}
335
336test "xor" {
337 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
338
339 try test_xor();
340 try comptime test_xor();
341}
342
343fn test_xor() !void {
344 try testOneXor(0xFF, 0x00, 0xFF);
345 try testOneXor(0xF0, 0x0F, 0xFF);
346 try testOneXor(0xFF, 0xF0, 0x0F);
347 try testOneXor(0xFF, 0x0F, 0xF0);
348 try testOneXor(0xFF, 0xFF, 0x00);
349}
350
351fn testOneXor(a: u8, b: u8, c: u8) !void {
352 try expect(a ^ b == c);
353}
354
355test "comptime_int xor" {
356 comptime {
357 try expect(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0x00000000000000000000000000000000 == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
358 try expect(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0x0000000000000000FFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
359 try expect(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x0000000000000000FFFFFFFFFFFFFFFF);
360 try expect(0x0000000000000000FFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFF0000000000000000);
361 try expect(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000000000000000000000000000);
362 try expect(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0x00000000FFFFFFFF00000000FFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
363 try expect(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000FFFFFFFF00000000FFFFFFFF);
364 try expect(0x00000000FFFFFFFF00000000FFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFF00000000FFFFFFFF00000000);
365 }
366}
367
368test "comptime_int param and return" {
369 const a = comptimeAdd(35361831660712422535336160538497375248, 101752735581729509668353361206450473702);
370 try expect(a == 137114567242441932203689521744947848950);
371
372 const b = comptimeAdd(594491908217841670578297176641415611445982232488944558774612, 390603545391089362063884922208143568023166603618446395589768);
373 try expect(b == 985095453608931032642182098849559179469148836107390954364380);
374}
375
376fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int {
377 return a + b;
378}
379
380fn not(comptime T: type, a: T) T {
381 return ~a;
382}
383
384test "binary not" {
385 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
386
387 try expect(not(u0, 0) == 0);
388 try expect(not(u1, 0) == 1);
389 try expect(not(u1, 1) == 0);
390 try expect(not(u5, 0b01001) == 0b10110);
391 try expect(not(u5, 0b10110) == 0b01001);
392 try expect(not(u16, 0b10101010_10101010) == 0b01010101_01010101);
393 try expect(not(u16, 0b01010101_01010101) == 0b10101010_10101010);
394 try expect(not(u32, 0xAAAA_3333) == 0x5555_CCCC);
395 try expect(not(u32, 0x5555_CCCC) == 0xAAAA_3333);
396 try expect(not(u35, 0x4_1111_FFFF) == 0x3_EEEE_0000);
397 try expect(not(u35, 0x3_EEEE_0000) == 0x4_1111_FFFF);
398 try expect(not(u48, 0x4567_89AB_CDEF) == 0xBA98_7654_3210);
399 try expect(not(u48, 0xBA98_7654_3210) == 0x4567_89AB_CDEF);
400 try expect(not(u64, 0x0123_4567_89AB_CDEF) == 0xFEDC_BA98_7654_3210);
401 try expect(not(u64, 0xFEDC_BA98_7654_3210) == 0x0123_4567_89AB_CDEF);
402
403 try expect(not(i1, 0) == -1);
404 try expect(not(i1, -1) == 0);
405 try expect(not(i5, -2) == 1);
406 try expect(not(i5, 3) == -4);
407 try expect(not(i32, 0) == -1);
408 try expect(not(i32, -2147483648) == 2147483647);
409 try expect(not(i64, -1) == 0);
410 try expect(not(i64, 0) == -1);
411
412 try expect(comptime x: {
413 break :x ~@as(u16, 0b1010101010101010) == 0b0101010101010101;
414 });
415 try expect(comptime x: {
416 break :x ~@as(u64, 2147483647) == 18446744071562067968;
417 });
418 try expect(comptime x: {
419 break :x ~@as(u0, 0) == 0;
420 });
421}
422
423test "binary not big int <= 128 bits" {
424 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
425 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
426 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
427
428 try expect(not(u65, 1) == 0x1_FFFFFFFF_FFFFFFFE);
429 try expect(not(u65, 0x1_FFFFFFFF_FFFFFFFE) == 1);
430
431 try expect(not(u96, 0x01234567_89ABCDEF_00000001) == 0xFEDCBA98_76543210_FFFFFFFE);
432 try expect(not(u96, 0xFEDCBA98_76543210_FFFFFFFE) == 0x01234567_89ABCDEF_00000001);
433
434 try expect(not(u128, 0xAAAAAAAA_AAAAAAAA_AAAAAAAA_AAAAAAAA) == 0x55555555_55555555_55555555_55555555);
435 try expect(not(u128, 0x55555555_55555555_55555555_55555555) == 0xAAAAAAAA_AAAAAAAA_AAAAAAAA_AAAAAAAA);
436
437 try expect(not(i65, -1) == 0);
438 try expect(not(i65, 0) == -1);
439 try expect(not(i65, -18446744073709551616) == 18446744073709551615);
440 try expect(not(i65, 18446744073709551615) == -18446744073709551616);
441
442 try expect(not(i128, -1) == 0);
443 try expect(not(i128, 0) == -1);
444 try expect(not(i128, -200) == 199);
445 try expect(not(i128, 199) == -200);
446
447 try expect(comptime x: {
448 break :x ~@as(u128, 0x55555555_55555555_55555555_55555555) == 0xaaaaaaaa_aaaaaaaa_aaaaaaaa_aaaaaaaa;
449 });
450 try expect(comptime x: {
451 break :x ~@as(i128, 0x55555555_55555555_55555555_55555555) == @as(i128, @bitCast(@as(u128, 0xaaaaaaaa_aaaaaaaa_aaaaaaaa_aaaaaaaa)));
452 });
453}
454
455test "division" {
456 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
457 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
458 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
459 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
460 try testIntDivision();
461 try comptime testIntDivision();
462
463 try testFloatDivision();
464 try comptime testFloatDivision();
465}
466
467fn testIntDivision() !void {
468 try expect(div(u32, 13, 3) == 4);
469 try expect(div(u64, 13, 3) == 4);
470 try expect(div(u8, 13, 3) == 4);
471
472 try expect(divExact(u32, 55, 11) == 5);
473 try expect(divExact(i32, -55, 11) == -5);
474 try expect(divExact(i64, -55, 11) == -5);
475 try expect(divExact(i16, -55, 11) == -5);
476
477 try expect(divFloor(i32, 5, 3) == 1);
478 try expect(divFloor(i32, -5, 3) == -2);
479 try expect(divFloor(i32, -0x80000000, -2) == 0x40000000);
480 try expect(divFloor(i32, 0, -0x80000000) == 0);
481 try expect(divFloor(i32, -0x40000001, 0x40000000) == -2);
482 try expect(divFloor(i32, -0x80000000, 1) == -0x80000000);
483 try expect(divFloor(i32, 10, 12) == 0);
484 try expect(divFloor(i32, -14, 12) == -2);
485 try expect(divFloor(i32, -2, 12) == -1);
486
487 try expect(divFloor(i8, 5, 3) == 1);
488 try expect(divFloor(i16, -5, 3) == -2);
489 try expect(divFloor(i64, -0x80000000, -2) == 0x40000000);
490 try expect(divFloor(i64, -0x40000001, 0x40000000) == -2);
491
492 try expect(divCeil(i32, 5, 3) == 2);
493 try expect(divCeil(i32, -5, 3) == -1);
494 try expect(divCeil(i32, -0x80000000, -2) == 0x40000000);
495 try expect(divCeil(i32, 0, -0x80000000) == 0);
496 try expect(divCeil(i32, -0x40000001, 0x40000000) == -1);
497 try expect(divCeil(i32, -0x80000000, 1) == -0x80000000);
498 try expect(divCeil(i32, 10, 12) == 1);
499 try expect(divCeil(i32, -14, 12) == -1);
500 try expect(divCeil(i32, -2, 12) == 0);
501
502 try expect(divCeil(u32, 5, 3) == 2);
503 try expect(divCeil(u32, 16, 4) == 4);
504 try expect(divCeil(u32, 0, 100) == 0);
505 try expect(divCeil(u32, maxInt(u32) - 1, 100) == 42949673);
506
507 try expect(divCeil(i64, 5, 3) == 2);
508 try expect(divCeil(i64, -5, 3) == -1);
509 try expect(divCeil(i64, -0x80000000, -2) == 0x40000000);
510 try expect(divCeil(i64, 0, -0x80000000) == 0);
511 try expect(divCeil(i64, -0x40000001, 0x40000000) == -1);
512 try expect(divCeil(i64, -0x80000000, 1) == -0x80000000);
513 try expect(divCeil(i64, 10, 12) == 1);
514 try expect(divCeil(i64, -14, 12) == -1);
515 try expect(divCeil(i64, -2, 12) == 0);
516
517 try expect(divCeil(u64, 5, 3) == 2);
518 try expect(divCeil(u64, 16, 4) == 4);
519 try expect(divCeil(u64, 0, 100) == 0);
520 try expect(divCeil(u64, maxInt(u64) - 1, 10000) == 1844674407370956);
521
522 try expect(divTrunc(i32, 5, 3) == 1);
523 try expect(divTrunc(i32, -5, 3) == -1);
524 try expect(divTrunc(i32, 9, -10) == 0);
525 try expect(divTrunc(i32, -9, 10) == 0);
526 try expect(divTrunc(i32, 10, 12) == 0);
527 try expect(divTrunc(i32, -14, 12) == -1);
528 try expect(divTrunc(i32, -2, 12) == 0);
529
530 try expect(mod(i32, 10, 12) == 10);
531 try expect(mod(i32, -14, 12) == 10);
532 try expect(mod(i32, -2, 12) == 10);
533 try expect(mod(i32, 10, -12) == -2);
534 try expect(mod(i32, -14, -12) == -2);
535 try expect(mod(i32, -2, -12) == -2);
536
537 try expect(mod(i64, -118, 12) == 2);
538 try expect(mod(u32, 10, 12) == 10);
539 try expect(mod(i64, -14, 12) == 10);
540 try expect(mod(i16, -2, 12) == 10);
541 try expect(mod(i16, -118, 12) == 2);
542 try expect(mod(i8, -2, 12) == 10);
543
544 try expect(rem(i64, -118, 12) == -10);
545 try expect(rem(i32, 10, 12) == 10);
546 try expect(rem(i32, -14, 12) == -2);
547 try expect(rem(i32, -2, 12) == -2);
548 try expect(rem(i32, 118, -12) == 10);
549 try expect(rem(i32, -14, -12) == -2);
550 try expect(rem(i16, -118, 12) == -10);
551
552 try expect(divTrunc(i20, 20, -5) == -4);
553 try expect(divTrunc(i20, -20, -4) == 5);
554
555 comptime {
556 try expect(
557 1194735857077236777412821811143690633098347576 % 508740759824825164163191790951174292733114988 == 177254337427586449086438229241342047632117600,
558 );
559 try expect(
560 @rem(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -177254337427586449086438229241342047632117600,
561 );
562 try expect(
563 1194735857077236777412821811143690633098347576 / 508740759824825164163191790951174292733114988 == 2,
564 );
565 try expect(
566 @divFloor(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -3,
567 );
568 try expect(
569 @divFloor(1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == -3,
570 );
571 try expect(
572 @divFloor(-1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == 2,
573 );
574 try expect(
575 @divCeil(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -2,
576 );
577 try expect(
578 @divCeil(1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == -2,
579 );
580 try expect(
581 @divCeil(-1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == 3,
582 );
583 try expect(
584 @divTrunc(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -2,
585 );
586 try expect(
587 @divTrunc(1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == -2,
588 );
589 try expect(
590 @divTrunc(-1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == 2,
591 );
592 try expect(
593 4126227191251978491697987544882340798050766755606969681711 % 10 == 1,
594 );
595 }
596}
597
598fn testFloatDivision() !void {
599 try expect(div(f32, 1.0, 2.0) == 0.5);
600
601 try expect(divExact(f32, 55.0, 11.0) == 5.0);
602 try expect(divExact(f32, -55.0, 11.0) == -5.0);
603
604 try expect(divFloor(f32, 5.0, 3.0) == 1.0);
605 try expect(divFloor(f32, -5.0, 3.0) == -2.0);
606 try expect(divFloor(f32, 56.0, 9.0) == 6.0);
607 try expect(divFloor(f32, 1053.0, -41.0) == -26.0);
608 try expect(divFloor(f16, -43.0, 12.0) == -4.0);
609 try expect(divFloor(f64, -90.0, -9.0) == 10.0);
610
611 try expect(divCeil(f32, 5.0, 3.0) == 2.0);
612 try expect(divCeil(f32, -5.0, 3.0) == -1.0);
613 try expect(divCeil(f32, 56.0, 9.0) == 7.0);
614 try expect(divCeil(f32, 1053.0, -41.0) == -25.0);
615 try expect(divCeil(f16, -43.0, 12.0) == -3.0);
616 try expect(divCeil(f64, -90.0, -9.0) == 10.0);
617
618 try expect(divTrunc(f32, 5.0, 3.0) == 1.0);
619 try expect(divTrunc(f32, -5.0, 3.0) == -1.0);
620 try expect(divTrunc(f32, 9.0, -10.0) == 0.0);
621 try expect(divTrunc(f32, -9.0, 10.0) == 0.0);
622 try expect(divTrunc(f64, 5.0, 3.0) == 1.0);
623 try expect(divTrunc(f64, -5.0, 3.0) == -1.0);
624 try expect(divTrunc(f64, 9.0, -10.0) == 0.0);
625 try expect(divTrunc(f64, -9.0, 10.0) == 0.0);
626}
627
628test "large integer division" {
629 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
630 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
631 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
632 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
633 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
634
635 {
636 var numerator: u256 = 99999999999999999997315645440;
637 var divisor: u256 = 10000000000000000000000000000;
638 _ = .{ &numerator, &divisor };
639 try expect(numerator / divisor == 9);
640 }
641 {
642 var numerator: u256 = 99999999999999999999000000000000000000000;
643 var divisor: u256 = 10000000000000000000000000000000000000000;
644 _ = .{ &numerator, &divisor };
645 try expect(numerator / divisor == 9);
646 }
647}
648
649test "division half-precision floats" {
650 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
651 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
652 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
653 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
654
655 try testDivisionFP16();
656 try comptime testDivisionFP16();
657}
658
659fn testDivisionFP16() !void {
660 try expect(div(f16, 1.0, 2.0) == 0.5);
661
662 try expect(divExact(f16, 55.0, 11.0) == 5.0);
663 try expect(divExact(f16, -55.0, 11.0) == -5.0);
664
665 try expect(divFloor(f16, 5.0, 3.0) == 1.0);
666 try expect(divFloor(f16, -5.0, 3.0) == -2.0);
667 try expect(divCeil(f16, 5.0, 3.0) == 2.0);
668 try expect(divCeil(f16, -5.0, 3.0) == -1.0);
669 try expect(divTrunc(f16, 5.0, 3.0) == 1.0);
670 try expect(divTrunc(f16, -5.0, 3.0) == -1.0);
671 try expect(divTrunc(f16, 9.0, -10.0) == 0.0);
672 try expect(divTrunc(f16, -9.0, 10.0) == 0.0);
673}
674
675fn div(comptime T: type, a: T, b: T) T {
676 return a / b;
677}
678fn divExact(comptime T: type, a: T, b: T) T {
679 return @divExact(a, b);
680}
681fn divFloor(comptime T: type, a: T, b: T) T {
682 return @divFloor(a, b);
683}
684fn divCeil(comptime T: type, a: T, b: T) T {
685 return @divCeil(a, b);
686}
687fn divTrunc(comptime T: type, a: T, b: T) T {
688 return @divTrunc(a, b);
689}
690fn mod(comptime T: type, a: T, b: T) T {
691 return @mod(a, b);
692}
693fn rem(comptime T: type, a: T, b: T) T {
694 return @rem(a, b);
695}
696
697test "unsigned wrapping" {
698 try testUnsignedWrappingEval(maxInt(u32));
699 try comptime testUnsignedWrappingEval(maxInt(u32));
700}
701fn testUnsignedWrappingEval(x: u32) !void {
702 const zero = x +% 1;
703 try expect(zero == 0);
704 const orig = zero -% 1;
705 try expect(orig == maxInt(u32));
706}
707
708test "signed wrapping" {
709 try testSignedWrappingEval(maxInt(i32));
710 try comptime testSignedWrappingEval(maxInt(i32));
711}
712fn testSignedWrappingEval(x: i32) !void {
713 const min_val = x +% 1;
714 try expect(min_val == minInt(i32));
715 const max_val = min_val -% 1;
716 try expect(max_val == maxInt(i32));
717}
718
719test "signed negation wrapping" {
720 try testSignedNegationWrappingEval(minInt(i16));
721 try comptime testSignedNegationWrappingEval(minInt(i16));
722}
723fn testSignedNegationWrappingEval(x: i16) !void {
724 try expect(x == -32768);
725 const neg = -%x;
726 try expect(neg == -32768);
727}
728
729test "unsigned negation wrapping" {
730 try testUnsignedNegationWrappingEval(1);
731 try comptime testUnsignedNegationWrappingEval(1);
732}
733fn testUnsignedNegationWrappingEval(x: u16) !void {
734 try expect(x == 1);
735 const neg = -%x;
736 try expect(neg == maxInt(u16));
737}
738
739test "negation wrapping" {
740 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
741 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
742
743 try expectEqual(@as(u1, 1), negateWrap(u1, 1));
744}
745
746fn negateWrap(comptime T: type, x: T) T {
747 // This is specifically testing a safety-checked add, so
748 // special case minInt(T) which would overflow otherwise.
749 return if (x == minInt(T)) minInt(T) else ~x + 1;
750}
751
752test "unsigned 64-bit division" {
753 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
754 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
755
756 try test_u64_div();
757 try comptime test_u64_div();
758}
759fn test_u64_div() !void {
760 const result = divWithResult(1152921504606846976, 34359738365);
761 try expect(result.quotient == 33554432);
762 try expect(result.remainder == 100663296);
763}
764fn divWithResult(a: u64, b: u64) DivResult {
765 return DivResult{
766 .quotient = a / b,
767 .remainder = a % b,
768 };
769}
770const DivResult = struct {
771 quotient: u64,
772 remainder: u64,
773};
774
775test "bit shift a u1" {
776 var x: u1 = 1;
777 _ = &x;
778 const y = x << 0;
779 try expect(y == 1);
780}
781
782test "truncating shift right" {
783 try testShrTrunc(maxInt(u16));
784 try comptime testShrTrunc(maxInt(u16));
785}
786fn testShrTrunc(x: u16) !void {
787 const shifted = x >> 1;
788 try expect(shifted == 32767);
789}
790
791test "f128" {
792 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
793 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
794 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
795 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
796
797 try test_f128();
798 try comptime test_f128();
799}
800
801fn make_f128(x: f128) f128 {
802 return x;
803}
804
805fn test_f128() !void {
806 try expect(@sizeOf(f128) == 16);
807 try expect(make_f128(1.0) == 1.0);
808 try expect(make_f128(1.0) != 1.1);
809 try expect(make_f128(1.0) > 0.9);
810 try expect(make_f128(1.0) >= 0.9);
811 try expect(make_f128(1.0) >= 1.0);
812 try should_not_be_zero(1.0);
813}
814
815fn should_not_be_zero(x: f128) !void {
816 try expect(x != 0.0);
817}
818
819test "umax wrapped squaring" {
820 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
821 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
822
823 {
824 var x: u4 = maxInt(u4);
825 x *%= x;
826 try expect(x == 1);
827 }
828 {
829 var x: u8 = maxInt(u8);
830 x *%= x;
831 try expect(x == 1);
832 }
833 {
834 var x: u12 = maxInt(u12);
835 x *%= x;
836 try expect(x == 1);
837 }
838 {
839 var x: u16 = maxInt(u16);
840 x *%= x;
841 try expect(x == 1);
842 }
843 {
844 var x: u24 = maxInt(u24);
845 x *%= x;
846 try expect(x == 1);
847 }
848 {
849 var x: u32 = maxInt(u32);
850 x *%= x;
851 try expect(x == 1);
852 }
853 {
854 var x: u48 = maxInt(u48);
855 x *%= x;
856 try expect(x == 1);
857 }
858 {
859 var x: u64 = maxInt(u64);
860 x *%= x;
861 try expect(x == 1);
862 }
863 {
864 var x: u96 = maxInt(u96);
865 x *%= x;
866 try expect(x == 1);
867 }
868 {
869 var x: u128 = maxInt(u128);
870 x *%= x;
871 try expect(x == 1);
872 }
873}
874
875test "128-bit multiplication" {
876 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
877 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
878 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
879
880 {
881 var a: i128 = 3;
882 var b: i128 = 2;
883 var c = a * b;
884 try expect(c == 6);
885
886 a = -3;
887 b = 2;
888 c = a * b;
889 try expect(c == -6);
890 }
891
892 {
893 var a: u128 = 0xffffffffffffffff;
894 var b: u128 = 100;
895 _ = .{ &a, &b };
896 const c = a * b;
897 try expect(c == 0x63ffffffffffffff9c);
898 }
899}
900
901fn testAddWithOverflow(comptime T: type, a: T, b: T, add: T, bit: u1) !void {
902 const ov = @addWithOverflow(a, b);
903 try expect(ov[0] == add);
904 try expect(ov[1] == bit);
905}
906
907test "@addWithOverflow" {
908 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
909 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
910 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
911
912 try testAddWithOverflow(u8, 250, 100, 94, 1);
913 try testAddWithOverflow(u8, 100, 150, 250, 0);
914
915 try testAddWithOverflow(u8, 200, 99, 43, 1);
916 try testAddWithOverflow(u8, 200, 55, 255, 0);
917
918 try testAddWithOverflow(usize, 6, 6, 12, 0);
919 try testAddWithOverflow(usize, maxInt(usize), 6, 5, 1);
920
921 try testAddWithOverflow(isize, -6, -6, -12, 0);
922 try testAddWithOverflow(isize, minInt(isize), -6, maxInt(isize) - 5, 1);
923}
924
925test "@addWithOverflow <= 128 bits" {
926 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
927 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
928 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
929
930 try testAddWithOverflow(u65, 4, 105, 109, 0);
931 try testAddWithOverflow(u65, 1000, 100, 1100, 0);
932 try testAddWithOverflow(u65, 100, maxInt(u65) - 99, 0, 1);
933 try testAddWithOverflow(u65, maxInt(u65), maxInt(u65), maxInt(u65) - 1, 1);
934 try testAddWithOverflow(u65, maxInt(u65) - 1, maxInt(u65), maxInt(u65) - 2, 1);
935 try testAddWithOverflow(u65, maxInt(u65), maxInt(u65) - 1, maxInt(u65) - 2, 1);
936
937 try testAddWithOverflow(u128, 4, 105, 109, 0);
938 try testAddWithOverflow(u128, 1000, 100, 1100, 0);
939 try testAddWithOverflow(u128, 100, maxInt(u128) - 99, 0, 1);
940 try testAddWithOverflow(u128, maxInt(u128), maxInt(u128), maxInt(u128) - 1, 1);
941 try testAddWithOverflow(u128, maxInt(u128) - 1, maxInt(u128), maxInt(u128) - 2, 1);
942 try testAddWithOverflow(u128, maxInt(u128), maxInt(u128) - 1, maxInt(u128) - 2, 1);
943
944 try testAddWithOverflow(i65, 4, -105, -101, 0);
945 try testAddWithOverflow(i65, 1000, 100, 1100, 0);
946 try testAddWithOverflow(i65, minInt(i65), 1, minInt(i65) + 1, 0);
947 try testAddWithOverflow(i65, maxInt(i65), minInt(i65), -1, 0);
948 try testAddWithOverflow(i65, minInt(i65), maxInt(i65), -1, 0);
949 try testAddWithOverflow(i65, maxInt(i65), -2, maxInt(i65) - 2, 0);
950 try testAddWithOverflow(i65, maxInt(i65), maxInt(i65), -2, 1);
951 try testAddWithOverflow(i65, minInt(i65), minInt(i65), 0, 1);
952 try testAddWithOverflow(i65, maxInt(i65) - 1, maxInt(i65), -3, 1);
953 try testAddWithOverflow(i65, maxInt(i65), maxInt(i65) - 1, -3, 1);
954
955 try testAddWithOverflow(i128, 4, -105, -101, 0);
956 try testAddWithOverflow(i128, 1000, 100, 1100, 0);
957 try testAddWithOverflow(i128, minInt(i128), 1, minInt(i128) + 1, 0);
958 try testAddWithOverflow(i128, maxInt(i128), minInt(i128), -1, 0);
959 try testAddWithOverflow(i128, minInt(i128), maxInt(i128), -1, 0);
960 try testAddWithOverflow(i128, maxInt(i128), -2, maxInt(i128) - 2, 0);
961 try testAddWithOverflow(i128, maxInt(i128), maxInt(i128), -2, 1);
962 try testAddWithOverflow(i128, minInt(i128), minInt(i128), 0, 1);
963 try testAddWithOverflow(i128, maxInt(i128) - 1, maxInt(i128), -3, 1);
964 try testAddWithOverflow(i128, maxInt(i128), maxInt(i128) - 1, -3, 1);
965}
966
967test "@addWithOverflow > 128 bits" {
968 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
969 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
970 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
971 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
972
973 try testAddWithOverflow(u129, 4, 105, 109, 0);
974 try testAddWithOverflow(u129, 1000, 100, 1100, 0);
975 try testAddWithOverflow(u129, 100, maxInt(u129) - 99, 0, 1);
976 try testAddWithOverflow(u129, maxInt(u129), maxInt(u129), maxInt(u129) - 1, 1);
977 try testAddWithOverflow(u129, maxInt(u129) - 1, maxInt(u129), maxInt(u129) - 2, 1);
978 try testAddWithOverflow(u129, maxInt(u129), maxInt(u129) - 1, maxInt(u129) - 2, 1);
979
980 try testAddWithOverflow(u400, 4, 105, 109, 0);
981 try testAddWithOverflow(u400, 1000, 100, 1100, 0);
982 try testAddWithOverflow(u400, 100, maxInt(u400) - 99, 0, 1);
983 try testAddWithOverflow(u400, maxInt(u400), maxInt(u400), maxInt(u400) - 1, 1);
984 try testAddWithOverflow(u400, maxInt(u400) - 1, maxInt(u400), maxInt(u400) - 2, 1);
985 try testAddWithOverflow(u400, maxInt(u400), maxInt(u400) - 1, maxInt(u400) - 2, 1);
986
987 try testAddWithOverflow(i129, 4, -105, -101, 0);
988 try testAddWithOverflow(i129, 1000, 100, 1100, 0);
989 try testAddWithOverflow(i129, minInt(i129), 1, minInt(i129) + 1, 0);
990 try testAddWithOverflow(i129, maxInt(i129), minInt(i129), -1, 0);
991 try testAddWithOverflow(i129, minInt(i129), maxInt(i129), -1, 0);
992 try testAddWithOverflow(i129, maxInt(i129), -2, maxInt(i129) - 2, 0);
993 try testAddWithOverflow(i129, maxInt(i129), maxInt(i129), -2, 1);
994 try testAddWithOverflow(i129, minInt(i129), minInt(i129), 0, 1);
995 try testAddWithOverflow(i129, maxInt(i129) - 1, maxInt(i129), -3, 1);
996 try testAddWithOverflow(i129, maxInt(i129), maxInt(i129) - 1, -3, 1);
997
998 try testAddWithOverflow(i400, 4, -105, -101, 0);
999 try testAddWithOverflow(i400, 1000, 100, 1100, 0);
1000 try testAddWithOverflow(i400, minInt(i400), 1, minInt(i400) + 1, 0);
1001 try testAddWithOverflow(i400, maxInt(i400), minInt(i400), -1, 0);
1002 try testAddWithOverflow(i400, minInt(i400), maxInt(i400), -1, 0);
1003 try testAddWithOverflow(i400, maxInt(i400), -2, maxInt(i400) - 2, 0);
1004 try testAddWithOverflow(i400, maxInt(i400), maxInt(i400), -2, 1);
1005 try testAddWithOverflow(i400, minInt(i400), minInt(i400), 0, 1);
1006 try testAddWithOverflow(i400, maxInt(i400) - 1, maxInt(i400), -3, 1);
1007 try testAddWithOverflow(i400, maxInt(i400), maxInt(i400) - 1, -3, 1);
1008}
1009
1010test "small int addition" {
1011 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1012 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1013 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
1014
1015 var x: u2 = 0;
1016 try expect(x == 0);
1017
1018 x += 1;
1019 try expect(x == 1);
1020
1021 x += 1;
1022 try expect(x == 2);
1023
1024 x += 1;
1025 try expect(x == 3);
1026
1027 const ov = @addWithOverflow(x, 1);
1028 try expect(ov[0] == 0);
1029 try expect(ov[1] == 1);
1030}
1031
1032fn testMulWithOverflow(comptime T: type, a: T, b: T, mul: T, bit: u1) !void {
1033 const ov = @mulWithOverflow(a, b);
1034 try expect(ov[0] == mul);
1035 try expect(ov[1] == bit);
1036}
1037
1038test "basic @mulWithOverflow" {
1039 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1040 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1041 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
1042
1043 try testMulWithOverflow(u8, 86, 3, 2, 1);
1044 try testMulWithOverflow(u8, 85, 3, 255, 0);
1045
1046 try testMulWithOverflow(u8, 123, 2, 246, 0);
1047 try testMulWithOverflow(u8, 123, 4, 236, 1);
1048}
1049
1050test "extensive @mulWithOverflow" {
1051 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1052 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1053 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1054
1055 try testMulWithOverflow(u5, 3, 10, 30, 0);
1056 try testMulWithOverflow(u5, 3, 11, 1, 1);
1057 try testMulWithOverflow(i5, 3, -5, -15, 0);
1058 try testMulWithOverflow(i5, 3, -6, 14, 1);
1059
1060 try testMulWithOverflow(u8, 3, 85, 255, 0);
1061 try testMulWithOverflow(u8, 3, 86, 2, 1);
1062 try testMulWithOverflow(i8, 3, -42, -126, 0);
1063 try testMulWithOverflow(i8, 3, -43, 127, 1);
1064
1065 try testMulWithOverflow(u14, 3, 0x1555, 0x3fff, 0);
1066 try testMulWithOverflow(u14, 3, 0x1556, 2, 1);
1067 try testMulWithOverflow(i14, 3, -0xaaa, -0x1ffe, 0);
1068 try testMulWithOverflow(i14, 3, -0xaab, 0x1fff, 1);
1069
1070 try testMulWithOverflow(u16, 3, 0x5555, 0xffff, 0);
1071 try testMulWithOverflow(u16, 3, 0x5556, 2, 1);
1072 try testMulWithOverflow(i16, 3, -0x2aaa, -0x7ffe, 0);
1073 try testMulWithOverflow(i16, 3, -0x2aab, 0x7fff, 1);
1074
1075 try testMulWithOverflow(u30, 3, 0x15555555, 0x3fffffff, 0);
1076 try testMulWithOverflow(u30, 3, 0x15555556, 2, 1);
1077 try testMulWithOverflow(i30, 3, -0xaaaaaaa, -0x1ffffffe, 0);
1078 try testMulWithOverflow(i30, 3, -0xaaaaaab, 0x1fffffff, 1);
1079
1080 try testMulWithOverflow(u32, 3, 0x55555555, 0xffffffff, 0);
1081 try testMulWithOverflow(u32, 3, 0x55555556, 2, 1);
1082 try testMulWithOverflow(i32, 3, -0x2aaaaaaa, -0x7ffffffe, 0);
1083 try testMulWithOverflow(i32, 3, -0x2aaaaaab, 0x7fffffff, 1);
1084
1085 try testMulWithOverflow(u31, 1 << 30, 1 << 30, 0, 1);
1086 try testMulWithOverflow(i31, minInt(i31), minInt(i31), 0, 1);
1087}
1088
1089test "@mulWithOverflow bitsize > 32" {
1090 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1091 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1092 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1093 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1094
1095 try testMulWithOverflow(u40, 3, 0x55_5555_5555, 0xff_ffff_ffff, 0);
1096 try testMulWithOverflow(u40, 3, 0x55_5555_5556, 2, 1);
1097 try testMulWithOverflow(u40, 0x10_0000_0000, 0x10_0000_0000, 0, 1);
1098
1099 try testMulWithOverflow(i40, 3, -0x2a_aaaa_aaaa, -0x7f_ffff_fffe, 0);
1100 try testMulWithOverflow(i40, 3, -0x2a_aaaa_aaab, 0x7f_ffff_ffff, 1);
1101 try testMulWithOverflow(i40, 6, -0x2a_aaaa_aaab, -2, 1);
1102 try testMulWithOverflow(i40, 0x08_0000_0000, -0x08_0000_0001, -0x8_0000_0000, 1);
1103
1104 try testMulWithOverflow(u62, 3, 0x1555555555555555, 0x3fffffffffffffff, 0);
1105 try testMulWithOverflow(u62, 3, 0x1555555555555556, 2, 1);
1106 try testMulWithOverflow(i62, 3, -0xaaaaaaaaaaaaaaa, -0x1ffffffffffffffe, 0);
1107 try testMulWithOverflow(i62, 3, -0xaaaaaaaaaaaaaab, 0x1fffffffffffffff, 1);
1108
1109 try testMulWithOverflow(u64, 3, 0x5555555555555555, 0xffffffffffffffff, 0);
1110 try testMulWithOverflow(u64, 3, 0x5555555555555556, 2, 1);
1111 try testMulWithOverflow(i64, 3, -0x2aaaaaaaaaaaaaaa, -0x7ffffffffffffffe, 0);
1112 try testMulWithOverflow(i64, 3, -0x2aaaaaaaaaaaaaab, 0x7fffffffffffffff, 1);
1113
1114 try testMulWithOverflow(u63, 1 << 62, 1 << 62, 0, 1);
1115 try testMulWithOverflow(i63, minInt(i63), minInt(i63), 0, 1);
1116}
1117
1118fn testMutiplyUnwrap(comptime T: type, wrapped_a: anyerror!T, comptime b: T, expected: T) !void {
1119 const a = try wrapped_a;
1120
1121 const c = a * b;
1122 try expect(expected == c);
1123}
1124
1125test "Multiply unwrap error * immediate" {
1126 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1127 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
1128 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1129 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
1130
1131 try testMutiplyUnwrap(i8, 3, -1, -3);
1132 try testMutiplyUnwrap(i16, 3, -1, -3);
1133 try testMutiplyUnwrap(i32, 3, -1, -3);
1134 try testMutiplyUnwrap(i64, 3, -1, -3);
1135}
1136
1137test "@mulWithOverflow bitsize 128 bits" {
1138 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1139 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1140 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1141 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1142 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
1143
1144 try testMulWithOverflow(u128, 3, 0x5555555555555555_5555555555555555, 0xffffffffffffffff_ffffffffffffffff, 0);
1145 try testMulWithOverflow(u128, 3, 0x5555555555555555_5555555555555556, 2, 1);
1146
1147 try testMulWithOverflow(u128, 1 << 100, 1 << 27, 1 << 127, 0);
1148 try testMulWithOverflow(u128, maxInt(u128), maxInt(u128), 1, 1);
1149 try testMulWithOverflow(u128, 1 << 100, 1 << 28, 0, 1);
1150 try testMulWithOverflow(u128, 1 << 127, 1 << 127, 0, 1);
1151
1152 try testMulWithOverflow(i128, 3, -0x2aaaaaaaaaaaaaaa_aaaaaaaaaaaaaaaa, -0x7fffffffffffffff_fffffffffffffffe, 0);
1153 try testMulWithOverflow(i128, 3, -0x2aaaaaaaaaaaaaaa_aaaaaaaaaaaaaaab, 0x7fffffffffffffff_ffffffffffffffff, 1);
1154 try testMulWithOverflow(i128, -1, -1, 1, 0);
1155 try testMulWithOverflow(i128, minInt(i128), minInt(i128), 0, 1);
1156
1157 try testMulWithOverflow(i128, 1 << 126, 1 << 1, -1 << 127, 1);
1158 try testMulWithOverflow(i128, -1 << 105, 1 << 22, -1 << 127, 0);
1159 try testMulWithOverflow(i128, 1 << 84, -1 << 43, -1 << 127, 0);
1160 try testMulWithOverflow(i128, -1 << 63, -1 << 64, -1 << 127, 1);
1161}
1162
1163test "@mulWithOverflow > 128 bits" {
1164 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1165 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1166
1167 try testMulWithOverflow(u140, 0, maxInt(u140), 0, 0);
1168 try testMulWithOverflow(u140, 1, maxInt(u140), maxInt(u140), 0);
1169 try testMulWithOverflow(u140, 1 << 70, 1 << 69, 1 << 139, 0);
1170 try testMulWithOverflow(u140, 1 << 70, 1 << 70, 0, 1);
1171
1172 try testMulWithOverflow(u200, 1 << 100, 1 << 99, 1 << 199, 0);
1173 try testMulWithOverflow(u200, 1 << 100, 1 << 100, 0, 1);
1174 try testMulWithOverflow(u200, maxInt(u200), maxInt(u200), 1, 1);
1175 try testMulWithOverflow(u200, maxInt(u200) - 1, 2, maxInt(u200) - 3, 1);
1176
1177 try testMulWithOverflow(i140, 0, -1, 0, 0);
1178 try testMulWithOverflow(i140, -1, -1, 1, 0);
1179 try testMulWithOverflow(i140, 1 << 69, 1 << 69, 1 << 138, 0);
1180 try testMulWithOverflow(i140, 1 << 69, 1 << 70, minInt(i140), 1);
1181 try testMulWithOverflow(i140, -1 << 70, 1 << 20, -1 << 90, 0);
1182 try testMulWithOverflow(i140, minInt(i140), -1, minInt(i140), 1);
1183
1184 try testMulWithOverflow(i200, 1 << 100, 1 << 98, 1 << 198, 0);
1185 try testMulWithOverflow(i200, 1 << 100, 1 << 99, minInt(i200), 1);
1186 try testMulWithOverflow(i200, -1 << 120, 1 << 30, -1 << 150, 0);
1187 try testMulWithOverflow(i200, minInt(i200), minInt(i200), 0, 1);
1188 try testMulWithOverflow(i200, maxInt(i200), 2, -2, 1);
1189 try testMulWithOverflow(i200, maxInt(i200), maxInt(i200), 1, 1);
1190}
1191
1192test "@mulWithOverflow bitsize 256 bits" {
1193 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1194 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1195 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1196
1197 {
1198 const const_lhs: u256 = 8035709466408580321693645878924206181189;
1199 const const_rhs: u256 = 343954217539185679456797259115612849079;
1200 const const_result = @mulWithOverflow(const_lhs, const_rhs);
1201 comptime assert(const_result[0] == 100698109432518020450541558444080472799095368135495022414802684874680804056403);
1202 comptime assert(const_result[1] == 1);
1203
1204 var var_lhs = const_lhs;
1205 var var_rhs = const_rhs;
1206 _ = .{ &var_lhs, &var_rhs };
1207 const var_result = @mulWithOverflow(var_lhs, var_rhs);
1208 try std.testing.expect(var_result[0] == const_result[0]);
1209 try std.testing.expect(var_result[1] == const_result[1]);
1210 }
1211 {
1212 const const_lhs: u256 = 100477140835310762407466294984162740292250605075409128262608;
1213 const const_rhs: u256 = 406310585934439581231;
1214 const const_result = @mulWithOverflow(const_lhs, const_rhs);
1215 comptime assert(const_result[0] == 66110554277021146912650321519727251744526528332039438002889524600764482652976);
1216 comptime assert(const_result[1] == 1);
1217
1218 var var_lhs = const_lhs;
1219 var var_rhs = const_rhs;
1220 _ = .{ &var_lhs, &var_rhs };
1221 const var_result = @mulWithOverflow(var_lhs, var_rhs);
1222 try std.testing.expect(var_result[0] == const_result[0]);
1223 try std.testing.expect(var_result[1] == const_result[1]);
1224 }
1225 try testMulWithOverflow(i256, 1 << 254, 1 << 1, -1 << 255, 1);
1226 try testMulWithOverflow(i256, -1 << 212, 1 << 43, -1 << 255, 0);
1227 try testMulWithOverflow(i256, 1 << 170, -1 << 85, -1 << 255, 0);
1228 try testMulWithOverflow(i256, -1 << 128, -1 << 127, -1 << 255, 1);
1229}
1230
1231fn testSubWithOverflow(comptime T: type, a: T, b: T, sub: T, bit: u1) !void {
1232 const ov = @subWithOverflow(a, b);
1233 try expect(ov[0] == sub);
1234 try expect(ov[1] == bit);
1235}
1236
1237test "@subWithOverflow" {
1238 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1239 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1240
1241 try testSubWithOverflow(u8, 1, 2, 255, 1);
1242 try testSubWithOverflow(u8, 1, 1, 0, 0);
1243
1244 try testSubWithOverflow(u16, 10000, 10002, 65534, 1);
1245 try testSubWithOverflow(u16, 10000, 9999, 1, 0);
1246
1247 try testSubWithOverflow(usize, 6, 6, 0, 0);
1248 try testSubWithOverflow(usize, 6, 7, maxInt(usize), 1);
1249 try testSubWithOverflow(isize, -6, -6, 0, 0);
1250 try testSubWithOverflow(isize, minInt(isize), 6, maxInt(isize) - 5, 1);
1251}
1252
1253test "@subWithOverflow <= 128 bits" {
1254 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1255 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1256 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1257
1258 try testSubWithOverflow(u65, 4, 105, maxInt(u65) - 100, 1);
1259 try testSubWithOverflow(u65, 1000, 100, 900, 0);
1260 try testSubWithOverflow(u65, maxInt(u65), maxInt(u65), 0, 0);
1261 try testSubWithOverflow(u65, maxInt(u65) - 1, maxInt(u65), maxInt(u65), 1);
1262 try testSubWithOverflow(u65, maxInt(u65), maxInt(u65) - 1, 1, 0);
1263
1264 try testSubWithOverflow(u128, 4, 105, maxInt(u128) - 100, 1);
1265 try testSubWithOverflow(u128, 1000, 100, 900, 0);
1266 try testSubWithOverflow(u128, maxInt(u128), maxInt(u128), 0, 0);
1267 try testSubWithOverflow(u128, maxInt(u128) - 1, maxInt(u128), maxInt(u128), 1);
1268 try testSubWithOverflow(u128, maxInt(u128), maxInt(u128) - 1, 1, 0);
1269
1270 try testSubWithOverflow(i65, 4, 105, -101, 0);
1271 try testSubWithOverflow(i65, 1000, 100, 900, 0);
1272 try testSubWithOverflow(i65, maxInt(i65), maxInt(i65), 0, 0);
1273 try testSubWithOverflow(i65, minInt(i65), minInt(i65), 0, 0);
1274 try testSubWithOverflow(i65, maxInt(i65) - 1, maxInt(i65), -1, 0);
1275 try testSubWithOverflow(i65, maxInt(i65), maxInt(i65) - 1, 1, 0);
1276 try testSubWithOverflow(i65, minInt(i65), 1, maxInt(i65), 1);
1277 try testSubWithOverflow(i65, maxInt(i65), minInt(i65), -1, 1);
1278 try testSubWithOverflow(i65, minInt(i65), maxInt(i65), 1, 1);
1279 try testSubWithOverflow(i65, maxInt(i65), -2, minInt(i65) + 1, 1);
1280
1281 try testSubWithOverflow(i128, 4, 105, -101, 0);
1282 try testSubWithOverflow(i128, 1000, 100, 900, 0);
1283 try testSubWithOverflow(i128, maxInt(i128), maxInt(i128), 0, 0);
1284 try testSubWithOverflow(i128, minInt(i128), minInt(i128), 0, 0);
1285 try testSubWithOverflow(i128, maxInt(i128) - 1, maxInt(i128), -1, 0);
1286 try testSubWithOverflow(i128, maxInt(i128), maxInt(i128) - 1, 1, 0);
1287 try testSubWithOverflow(i128, minInt(i128), 1, maxInt(i128), 1);
1288 try testSubWithOverflow(i128, maxInt(i128), minInt(i128), -1, 1);
1289 try testSubWithOverflow(i128, minInt(i128), maxInt(i128), 1, 1);
1290 try testSubWithOverflow(i128, maxInt(i128), -2, minInt(i128) + 1, 1);
1291}
1292
1293test "@subWithOverflow > 128 bits" {
1294 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1295 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1296 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1297 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
1298
1299 try testSubWithOverflow(u129, 4, 105, maxInt(u129) - 100, 1);
1300 try testSubWithOverflow(u129, 1000, 100, 900, 0);
1301 try testSubWithOverflow(u129, maxInt(u129), maxInt(u129), 0, 0);
1302 try testSubWithOverflow(u129, maxInt(u129) - 1, maxInt(u129), maxInt(u129), 1);
1303 try testSubWithOverflow(u129, maxInt(u129), maxInt(u129) - 1, 1, 0);
1304
1305 try testSubWithOverflow(u400, 4, 105, maxInt(u400) - 100, 1);
1306 try testSubWithOverflow(u400, 1000, 100, 900, 0);
1307 try testSubWithOverflow(u400, maxInt(u400), maxInt(u400), 0, 0);
1308 try testSubWithOverflow(u400, maxInt(u400) - 1, maxInt(u400), maxInt(u400), 1);
1309 try testSubWithOverflow(u400, maxInt(u400), maxInt(u400) - 1, 1, 0);
1310
1311 try testSubWithOverflow(i129, 4, 105, -101, 0);
1312 try testSubWithOverflow(i129, 1000, 100, 900, 0);
1313 try testSubWithOverflow(i129, maxInt(i129), maxInt(i129), 0, 0);
1314 try testSubWithOverflow(i129, minInt(i129), minInt(i129), 0, 0);
1315 try testSubWithOverflow(i129, maxInt(i129) - 1, maxInt(i129), -1, 0);
1316 try testSubWithOverflow(i129, maxInt(i129), maxInt(i129) - 1, 1, 0);
1317 try testSubWithOverflow(i129, minInt(i129), 1, maxInt(i129), 1);
1318 try testSubWithOverflow(i129, maxInt(i129), minInt(i129), -1, 1);
1319 try testSubWithOverflow(i129, minInt(i129), maxInt(i129), 1, 1);
1320 try testSubWithOverflow(i129, maxInt(i129), -2, minInt(i129) + 1, 1);
1321
1322 try testSubWithOverflow(i400, 4, 105, -101, 0);
1323 try testSubWithOverflow(i400, 1000, 100, 900, 0);
1324 try testSubWithOverflow(i400, maxInt(i400), maxInt(i400), 0, 0);
1325 try testSubWithOverflow(i400, minInt(i400), minInt(i400), 0, 0);
1326 try testSubWithOverflow(i400, maxInt(i400) - 1, maxInt(i400), -1, 0);
1327 try testSubWithOverflow(i400, maxInt(i400), maxInt(i400) - 1, 1, 0);
1328 try testSubWithOverflow(i400, minInt(i400), 1, maxInt(i400), 1);
1329 try testSubWithOverflow(i400, maxInt(i400), minInt(i400), -1, 1);
1330 try testSubWithOverflow(i400, minInt(i400), maxInt(i400), 1, 1);
1331 try testSubWithOverflow(i400, maxInt(i400), -2, minInt(i400) + 1, 1);
1332}
1333
1334fn testShlWithOverflow(comptime T: type, a: T, b: math.Log2Int(T), shl: T, bit: u1) !void {
1335 const ov = @shlWithOverflow(a, b);
1336 try expect(ov[0] == shl);
1337 try expect(ov[1] == bit);
1338}
1339
1340test "@shlWithOverflow" {
1341 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1342 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1343 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1344 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1345
1346 try testShlWithOverflow(u4, 2, 1, 4, 0);
1347 try testShlWithOverflow(u4, 2, 3, 0, 1);
1348
1349 try testShlWithOverflow(i9, 127, 1, 254, 0);
1350 try testShlWithOverflow(i9, 127, 2, -4, 1);
1351
1352 try testShlWithOverflow(u16, 0b0010111111111111, 3, 0b0111111111111000, 1);
1353 try testShlWithOverflow(u16, 0b0010111111111111, 2, 0b1011111111111100, 0);
1354
1355 try testShlWithOverflow(u16, 0b0000_0000_0000_0011, 15, 0b1000_0000_0000_0000, 1);
1356 try testShlWithOverflow(u16, 0b0000_0000_0000_0011, 14, 0b1100_0000_0000_0000, 0);
1357}
1358
1359test "@shlWithOverflow > 64 bits" {
1360 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1361 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1362 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1363 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1364
1365 try testShlWithOverflow(u65, 0x0_0100_0000_0000_0000, 7, 0x0_8000_0000_0000_0000, 0);
1366 try testShlWithOverflow(u65, 0x0_0100_0000_0000_0000, 8, 0x1_0000_0000_0000_0000, 0);
1367 try testShlWithOverflow(u65, 0x0_0100_0000_0000_0000, 9, 0, 1);
1368 try testShlWithOverflow(u65, 0x0_0100_0000_0000_0000, 10, 0, 1);
1369
1370 try testShlWithOverflow(u128, 0x0100_0000_0000_0000_0000000000000000, 6, 0x4000_0000_0000_0000_0000000000000000, 0);
1371 try testShlWithOverflow(u128, 0x0100_0000_0000_0000_0000000000000000, 7, 0x8000_0000_0000_0000_0000000000000000, 0);
1372 try testShlWithOverflow(u128, 0x0100_0000_0000_0000_0000000000000000, 8, 0, 1);
1373 try testShlWithOverflow(u128, 0x0100_0000_0000_0000_0000000000000000, 9, 0, 1);
1374
1375 try testShlWithOverflow(i65, 0x0_0100_0000_0000_0000, 7, 0x0_8000_0000_0000_0000, 0);
1376 try testShlWithOverflow(i65, 0x0_0100_0000_0000_0000, 8, minInt(i65), 1);
1377 try testShlWithOverflow(i65, 0x0_0100_0000_0000_0000, 9, 0, 1);
1378 try testShlWithOverflow(i65, 0x0_0100_0000_0000_0000, 10, 0, 1);
1379
1380 try testShlWithOverflow(i128, 0x0100_0000_0000_0000_0000000000000000, 6, 0x4000_0000_0000_0000_0000000000000000, 0);
1381 try testShlWithOverflow(i128, 0x0100_0000_0000_0000_0000000000000000, 7, minInt(i128), 1);
1382 try testShlWithOverflow(i128, 0x0100_0000_0000_0000_0000000000000000, 8, 0, 1);
1383 try testShlWithOverflow(i128, 0x0100_0000_0000_0000_0000000000000000, 9, 0, 1);
1384}
1385
1386test "@shlWithOverflow > 128 bits" {
1387 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1388 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1389
1390 try testShlWithOverflow(u140, 1 << 100, 20, 1 << 120, 0);
1391 try testShlWithOverflow(u140, 1 << 100, 40, 0, 1);
1392 try testShlWithOverflow(u140, 3, 138, (1 << 139) | (1 << 138), 0);
1393 try testShlWithOverflow(u140, 7, 138, (1 << 139) | (1 << 138), 1);
1394
1395 try testShlWithOverflow(u256, 1 << 200, 40, 1 << 240, 0);
1396 try testShlWithOverflow(u256, 1 << 200, 55, 1 << 255, 0);
1397 try testShlWithOverflow(u256, 1 << 200, 56, 0, 1);
1398 try testShlWithOverflow(u256, maxInt(u256), 1, maxInt(u256) - 1, 1);
1399
1400 try testShlWithOverflow(i140, 1 << 100, 20, 1 << 120, 0);
1401 try testShlWithOverflow(i140, 1 << 100, 39, minInt(i140), 1);
1402 try testShlWithOverflow(i140, -1 << 20, 10, -1 << 30, 0);
1403 try testShlWithOverflow(i140, minInt(i140), 1, 0, 1);
1404
1405 try testShlWithOverflow(i256, 1 << 200, 30, 1 << 230, 0);
1406 try testShlWithOverflow(i256, 1 << 200, 55, minInt(i256), 1);
1407 try testShlWithOverflow(i256, -1 << 120, 40, -1 << 160, 0);
1408 try testShlWithOverflow(i256, minInt(i256), 1, 0, 1);
1409}
1410
1411fn testAnd(comptime T: type, a: T, b: T, expected: T) !void {
1412 try expect((a & b) == expected);
1413}
1414
1415test "and > 128 bits" {
1416 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1417
1418 try testAnd(u140, (1 << 139) | (1 << 70) | 0xaa, (1 << 139) | (1 << 69) | 0xcc, (1 << 139) | 0x88);
1419 try testAnd(u140, maxInt(u140), 1 << 100, 1 << 100);
1420 try testAnd(u140, 0, maxInt(u140), 0);
1421 try testAnd(u140, (1 << 80) | (1 << 17) | 1, (1 << 17) | (1 << 9) | 1, (1 << 17) | 1);
1422
1423 try testAnd(u256, maxInt(u256), (1 << 255) | (1 << 200) | 7, (1 << 255) | (1 << 200) | 7);
1424 try testAnd(u256, (1 << 255) | (1 << 5), (1 << 254) | (1 << 5), 1 << 5);
1425 try testAnd(u256, (1 << 130) | (1 << 64) | (1 << 2), (1 << 130) | (1 << 63) | (1 << 2), (1 << 130) | (1 << 2));
1426 try testAnd(u256, 0, 1 << 200, 0);
1427
1428 try testAnd(i140, -1, 1 << 17, 1 << 17);
1429 try testAnd(i140, minInt(i140), -1, minInt(i140));
1430 try testAnd(i140, -1 << 40, (1 << 100) | (1 << 80) | (1 << 40), (1 << 100) | (1 << 80) | (1 << 40));
1431 try testAnd(i140, 0, maxInt(i140), 0);
1432
1433 try testAnd(i256, -1, 1 << 200, 1 << 200);
1434 try testAnd(i256, minInt(i256), maxInt(i256), 0);
1435 try testAnd(i256, -1 << 130, -1 << 129, -1 << 130);
1436 try testAnd(i256, minInt(i256), -1 << 10, minInt(i256));
1437}
1438
1439fn testOr(comptime T: type, a: T, b: T, expected: T) !void {
1440 try expect((a | b) == expected);
1441}
1442
1443test "or > 128 bits" {
1444 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1445
1446 try testOr(u140, 0, 1 << 139, 1 << 139);
1447 try testOr(u140, (1 << 70) | 0xa, (1 << 69) | 0x5, (1 << 70) | (1 << 69) | 0xf);
1448 try testOr(u140, maxInt(u140), 0, maxInt(u140));
1449 try testOr(u140, (1 << 17) | (1 << 3), (1 << 17) | (1 << 1), (1 << 17) | 0xa);
1450
1451 try testOr(u256, 0, 1 << 255, 1 << 255);
1452 try testOr(u256, (1 << 200) | 0x30, (1 << 199) | 0x0f, (1 << 200) | (1 << 199) | 0x3f);
1453 try testOr(u256, maxInt(u256), 1 << 17, maxInt(u256));
1454 try testOr(u256, 1 << 130, 1 << 64, (1 << 130) | (1 << 64));
1455
1456 try testOr(i140, -1, 0, -1);
1457 try testOr(i140, minInt(i140), 1, minInt(i140) + 1);
1458 try testOr(i140, -1 << 40, (1 << 5) | 1, (-1 << 40) | 0x21);
1459 try testOr(i140, 0, maxInt(i140), maxInt(i140));
1460
1461 try testOr(i256, -1, 1 << 200, -1);
1462 try testOr(i256, minInt(i256), 1 << 17, minInt(i256) | (1 << 17));
1463 try testOr(i256, -1 << 130, 0xff, (-1 << 130) | 0xff);
1464 try testOr(i256, 0, maxInt(i256), maxInt(i256));
1465}
1466
1467fn testXor(comptime T: type, a: T, b: T, expected: T) !void {
1468 try expect((a ^ b) == expected);
1469}
1470
1471test "xor > 128 bits" {
1472 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1473
1474 try testXor(u140, 0, maxInt(u140), maxInt(u140));
1475 try testXor(u140, 1 << 139, 1 << 139, 0);
1476 try testXor(u140, (1 << 70) | 0xa, (1 << 69) | 0x5, (1 << 70) | (1 << 69) | 0xf);
1477 try testXor(u140, maxInt(u140), 1 << 100, maxInt(u140) ^ (1 << 100));
1478
1479 try testXor(u256, 0, maxInt(u256), maxInt(u256));
1480 try testXor(u256, 1 << 255, 1 << 255, 0);
1481 try testXor(u256, (1 << 200) | (1 << 5), (1 << 199) | (1 << 5), (1 << 200) | (1 << 199));
1482 try testXor(u256, maxInt(u256), 1 << 17, maxInt(u256) ^ (1 << 17));
1483
1484 try testXor(i140, -1, -1, 0);
1485 try testXor(i140, -1, 0, -1);
1486 try testXor(i140, minInt(i140), -1, maxInt(i140));
1487 try testXor(i140, -1 << 40, -1 << 39, 1 << 39);
1488
1489 try testXor(i256, -1, -1, 0);
1490 try testXor(i256, -1, 0, -1);
1491 try testXor(i256, minInt(i256), -1, maxInt(i256));
1492 try testXor(i256, -1 << 130, -1 << 129, 1 << 129);
1493}
1494
1495fn testNot(comptime T: type, a: T, expected: T) !void {
1496 try expect((~a) == expected);
1497}
1498
1499test "not > 128 bits" {
1500 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1501
1502 try testNot(u140, 0, maxInt(u140));
1503 try testNot(u140, maxInt(u140), 0);
1504 try testNot(u140, 1 << 139, maxInt(u140) ^ (1 << 139));
1505 try testNot(u140, (1 << 17) | 1, maxInt(u140) ^ ((1 << 17) | 1));
1506
1507 try testNot(u256, 0, maxInt(u256));
1508 try testNot(u256, maxInt(u256), 0);
1509 try testNot(u256, 1 << 255, maxInt(u256) ^ (1 << 255));
1510 try testNot(u256, (1 << 200) | (1 << 5), maxInt(u256) ^ ((1 << 200) | (1 << 5)));
1511
1512 try testNot(i140, -1, 0);
1513 try testNot(i140, 0, -1);
1514 try testNot(i140, minInt(i140), maxInt(i140));
1515 try testNot(i140, -1 << 10, (1 << 10) - 1);
1516
1517 try testNot(i256, -1, 0);
1518 try testNot(i256, 0, -1);
1519 try testNot(i256, minInt(i256), maxInt(i256));
1520 try testNot(i256, -1 << 200, (1 << 200) - 1);
1521}
1522
1523fn testShl(comptime T: type, a: T, b: std.math.Log2Int(T), expected: T) !void {
1524 try expect((a << b) == expected);
1525}
1526
1527test "shl > 128 bits" {
1528 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1529
1530 try testShl(u140, 1 << 5, 10, 1 << 15);
1531 try testShl(u140, 3, 138, (1 << 139) | (1 << 138));
1532 try testShl(u140, 1 << 139, 1, 0);
1533 try testShl(u140, (1 << 70) | 1, 3, (1 << 73) | 8);
1534
1535 try testShl(u256, 1 << 200, 20, 1 << 220);
1536 try testShl(u256, 1 << 255, 1, 0);
1537 try testShl(u256, (1 << 128) | 5, 7, (1 << 135) | 0x280);
1538 try testShl(u256, maxInt(u256), 1, maxInt(u256) - 1);
1539
1540 try testShl(i140, 1 << 20, 5, 1 << 25);
1541 try testShl(i140, -1, 7, -128);
1542 try testShl(i140, minInt(i140), 1, 0);
1543 try testShl(i140, -1 << 10, 5, -1 << 15);
1544
1545 try testShl(i256, 1 << 200, 30, 1 << 230);
1546 try testShl(i256, -1, 200, -1 << 200);
1547 try testShl(i256, minInt(i256), 1, 0);
1548 try testShl(i256, -1 << 100, 50, -1 << 150);
1549}
1550
1551fn testShr(comptime T: type, a: T, b: std.math.Log2Int(T), expected: T) !void {
1552 try expect((a >> b) == expected);
1553}
1554
1555test "shr > 128 bits" {
1556 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1557
1558 try testShr(u140, 1 << 139, 39, 1 << 100);
1559 try testShr(u140, (1 << 70) | 8, 3, (1 << 67) | 1);
1560 try testShr(u140, 1, 1, 0);
1561 try testShr(u140, maxInt(u140), 139, 1);
1562
1563 try testShr(u256, 1 << 255, 55, 1 << 200);
1564 try testShr(u256, (1 << 200) | (1 << 7), 7, (1 << 193) | 1);
1565 try testShr(u256, 1, 1, 0);
1566 try testShr(u256, maxInt(u256), 255, 1);
1567
1568 try testShr(i140, -1, 17, -1);
1569 try testShr(i140, minInt(i140), 1, minInt(i140) >> 1);
1570 try testShr(i140, -1 << 80, 40, -1 << 40);
1571 try testShr(i140, -5, 1, -3);
1572
1573 try testShr(i256, -1, 200, -1);
1574 try testShr(i256, minInt(i256), 1, minInt(i256) >> 1);
1575 try testShr(i256, -1 << 180, 80, -1 << 100);
1576 try testShr(i256, -5, 1, -3);
1577}
1578
1579fn testClz(comptime T: type, a: T, expected: u16) !void {
1580 try expect(@clz(a) == expected);
1581}
1582
1583test "@clz > 128 bits" {
1584 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1585 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1586
1587 try testClz(u140, 0, 140);
1588 try testClz(u140, 1 << 139, 0);
1589 try testClz(u140, 1 << 70, 69);
1590 try testClz(u140, maxInt(u140), 0);
1591
1592 try testClz(u256, 0, 256);
1593 try testClz(u256, 1 << 255, 0);
1594 try testClz(u256, 1 << 200, 55);
1595 try testClz(u256, 1, 255);
1596
1597 try testClz(i140, -1, 0);
1598 try testClz(i140, minInt(i140), 0);
1599 try testClz(i140, 1 << 70, 69);
1600 try testClz(i140, 0, 140);
1601
1602 try testClz(i256, -1, 0);
1603 try testClz(i256, minInt(i256), 0);
1604 try testClz(i256, 1 << 200, 55);
1605 try testClz(i256, 0, 256);
1606}
1607
1608fn testCtz(comptime T: type, a: T, expected: u16) !void {
1609 try expect(@ctz(a) == expected);
1610}
1611
1612test "@ctz > 128 bits" {
1613 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1614 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1615
1616 try testCtz(u140, 0, 140);
1617 try testCtz(u140, 1 << 139, 139);
1618 try testCtz(u140, 1 << 70, 70);
1619 try testCtz(u140, maxInt(u140), 0);
1620
1621 try testCtz(u256, 0, 256);
1622 try testCtz(u256, 1 << 255, 255);
1623 try testCtz(u256, 1 << 200, 200);
1624 try testCtz(u256, 3 << 5, 5);
1625
1626 try testCtz(i140, -1, 0);
1627 try testCtz(i140, minInt(i140), 139);
1628 try testCtz(i140, 0, 140);
1629 try testCtz(i140, -1 << 70, 70);
1630
1631 try testCtz(i256, -1, 0);
1632 try testCtz(i256, minInt(i256), 255);
1633 try testCtz(i256, 0, 256);
1634 try testCtz(i256, -1 << 200, 200);
1635}
1636
1637fn testPopCount(comptime T: type, a: T, expected: u16) !void {
1638 try expect(@popCount(a) == expected);
1639}
1640
1641test "@popCount > 128 bits" {
1642 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1643 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1644
1645 try testPopCount(u140, 0, 0);
1646 try testPopCount(u140, maxInt(u140), 140);
1647 try testPopCount(u140, (1 << 139) | (1 << 70) | 1, 3);
1648 try testPopCount(u140, (1 << 5) - 1, 5);
1649
1650 try testPopCount(u256, 0, 0);
1651 try testPopCount(u256, maxInt(u256), 256);
1652 try testPopCount(u256, (1 << 255) | (1 << 200) | (1 << 17) | (1 << 3), 4);
1653 try testPopCount(u256, (1 << 64) - 1, 64);
1654
1655 try testPopCount(i140, -1, 140);
1656 try testPopCount(i140, minInt(i140), 1);
1657 try testPopCount(i140, 0, 0);
1658 try testPopCount(i140, -1 << 70, 70);
1659
1660 try testPopCount(i256, -1, 256);
1661 try testPopCount(i256, minInt(i256), 1);
1662 try testPopCount(i256, 0, 0);
1663 try testPopCount(i256, -1 << 200, 56);
1664}
1665
1666fn testBitReverse(comptime T: type, a: T, expected: T) !void {
1667 try expect(@bitReverse(a) == expected);
1668}
1669
1670test "@bitReverse > 128 bits" {
1671 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1672 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1673
1674 try testBitReverse(u140, 1 << 139, 1);
1675 try testBitReverse(u140, 1 << 70, 1 << 69);
1676 try testBitReverse(u140, 0, 0);
1677 try testBitReverse(u140, maxInt(u140), maxInt(u140));
1678
1679 try testBitReverse(u256, 1 << 255, 1);
1680 try testBitReverse(u256, 1 << 200, 1 << 55);
1681 try testBitReverse(u256, 0, 0);
1682 try testBitReverse(u256, maxInt(u256), maxInt(u256));
1683
1684 try testBitReverse(i140, -1, -1);
1685 try testBitReverse(i140, minInt(i140), 1);
1686 try testBitReverse(i140, 1 << 70, 1 << 69);
1687 try testBitReverse(i140, 0, 0);
1688
1689 try testBitReverse(i256, -1, -1);
1690 try testBitReverse(i256, minInt(i256), 1);
1691 try testBitReverse(i256, 1 << 200, 1 << 55);
1692 try testBitReverse(i256, 0, 0);
1693}
1694
1695fn testByteSwap(comptime T: type, a: T, expected: T) !void {
1696 try expect(@byteSwap(a) == expected);
1697}
1698
1699test "@byteSwap > 128 bits" {
1700 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1701 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1702
1703 try testByteSwap(u144, 1 << 136, 1);
1704 try testByteSwap(u144, 1, 1 << 136);
1705 try testByteSwap(u144, 0, 0);
1706 try testByteSwap(u144, maxInt(u144), maxInt(u144));
1707
1708 try testByteSwap(u256, 1 << 248, 1);
1709 try testByteSwap(u256, 1 << 120, 1 << 128);
1710 try testByteSwap(u256, 1, 1 << 248);
1711 try testByteSwap(u256, maxInt(u256), maxInt(u256));
1712
1713 try testByteSwap(i144, -1, -1);
1714 try testByteSwap(i144, minInt(i144), 128);
1715 try testByteSwap(i144, 1, 1 << 136);
1716 try testByteSwap(i144, 1 << 64, 1 << 72);
1717
1718 try testByteSwap(i256, -1, -1);
1719 try testByteSwap(i256, minInt(i256), 128);
1720 try testByteSwap(i256, 1, 1 << 248);
1721 try testByteSwap(i256, 1 << 120, 1 << 128);
1722}
1723
1724fn testMax(comptime T: type, a: T, b: T, expected: T) !void {
1725 try expect(@max(a, b) == expected);
1726}
1727
1728test "@max > 128 bits" {
1729 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1730 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1731
1732 try testMax(u140, 0, maxInt(u140), maxInt(u140));
1733 try testMax(u140, 1 << 139, 1 << 138, 1 << 139);
1734 try testMax(u140, (1 << 100) + 7, (1 << 100) + 3, (1 << 100) + 7);
1735 try testMax(u140, maxInt(u140) - 1, maxInt(u140), maxInt(u140));
1736
1737 try testMax(u200, 1 << 199, 1 << 198, 1 << 199);
1738 try testMax(u200, (1 << 150) + (1 << 17), (1 << 150) + (1 << 18), (1 << 150) + (1 << 18));
1739 try testMax(u200, 0, 1 << 123, 1 << 123);
1740 try testMax(u200, maxInt(u200), maxInt(u200) - 1, maxInt(u200));
1741
1742 try testMax(i140, -1, 0, 0);
1743 try testMax(i140, minInt(i140), maxInt(i140), maxInt(i140));
1744 try testMax(i140, -1 << 70, -1 << 69, -1 << 69);
1745 try testMax(i140, (1 << 100) - 1, 1 << 100, 1 << 100);
1746
1747 try testMax(i200, -1, minInt(i200), -1);
1748 try testMax(i200, -1 << 150, -1 << 149, -1 << 149);
1749 try testMax(i200, 1 << 198, (1 << 198) - 1, 1 << 198);
1750 try testMax(i200, maxInt(i200), 0, maxInt(i200));
1751}
1752
1753fn testMin(comptime T: type, a: T, b: T, expected: T) !void {
1754 try expect(@min(a, b) == expected);
1755}
1756
1757test "@min > 128 bits" {
1758 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1759 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1760
1761 try testMin(u140, 0, maxInt(u140), 0);
1762 try testMin(u140, 1 << 139, 1 << 138, 1 << 138);
1763 try testMin(u140, (1 << 100) + 7, (1 << 100) + 3, (1 << 100) + 3);
1764 try testMin(u140, maxInt(u140) - 1, maxInt(u140), maxInt(u140) - 1);
1765
1766 try testMin(u200, 1 << 199, 1 << 198, 1 << 198);
1767 try testMin(u200, (1 << 150) + (1 << 17), (1 << 150) + (1 << 18), (1 << 150) + (1 << 17));
1768 try testMin(u200, 0, 1 << 123, 0);
1769 try testMin(u200, maxInt(u200), maxInt(u200) - 1, maxInt(u200) - 1);
1770
1771 try testMin(i140, -1, 0, -1);
1772 try testMin(i140, minInt(i140), maxInt(i140), minInt(i140));
1773 try testMin(i140, -1 << 70, -1 << 69, -1 << 70);
1774 try testMin(i140, (1 << 100) - 1, 1 << 100, (1 << 100) - 1);
1775
1776 try testMin(i200, -1, minInt(i200), minInt(i200));
1777 try testMin(i200, -1 << 150, -1 << 149, -1 << 150);
1778 try testMin(i200, 1 << 198, (1 << 198) - 1, (1 << 198) - 1);
1779 try testMin(i200, maxInt(i200), 0, 0);
1780}
1781
1782fn testAbs(comptime T: type, a: T, expected: anytype) !void {
1783 try expect(@abs(a) == expected);
1784}
1785
1786test "@abs > 128 bits" {
1787 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1788
1789 try testAbs(u140, 0, 0);
1790 try testAbs(u140, 1 << 139, 1 << 139);
1791 try testAbs(u200, 123456789, 123456789);
1792 try testAbs(u200, maxInt(u200), maxInt(u200));
1793
1794 try testAbs(i140, 0, 0);
1795 try testAbs(i140, 1, 1);
1796 try testAbs(i140, -1, 1);
1797 try testAbs(i140, minInt(i140), 1 << 139);
1798
1799 try testAbs(i200, 1 << 198, 1 << 198);
1800 try testAbs(i200, -1 << 198, 1 << 198);
1801 try testAbs(i200, maxInt(i200), maxInt(i200));
1802 try testAbs(i200, minInt(i200), 1 << 199);
1803}
1804
1805fn testRem(comptime T: type, numerator: T, denominator: T, expected: T) !void {
1806 try expect(@rem(numerator, denominator) == expected);
1807}
1808
1809test "@rem > 128 bits" {
1810 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1811 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1812
1813 try testRem(u140, 0, maxInt(u140), 0);
1814 try testRem(u140, maxInt(u140), maxInt(u140), 0);
1815 try testRem(u140, maxInt(u140), 2, 1);
1816 try testRem(u140, (1 << 139) + 5, 1 << 70, 5);
1817 try testRem(u140, (1 << 100) + (1 << 50) + 7, 1 << 50, 7);
1818 try testRem(u200, 123, 1 << 100, 123);
1819 try testRem(u200, 1 << 120, 1 << 60, 0);
1820 try testRem(u200, maxInt(u200), 1 << 100, (1 << 100) - 1);
1821
1822 try testRem(i140, 0, maxInt(i140), 0);
1823 try testRem(i140, maxInt(i140), maxInt(i140), 0);
1824 try testRem(i140, -((1 << 100) + 1), 1 << 50, -1);
1825 try testRem(i140, (1 << 100) + 1, -(1 << 50), 1);
1826 try testRem(i140, -((1 << 100) + 1), -(1 << 50), -1);
1827 try testRem(i200, minInt(i200), 1, 0);
1828 try testRem(i200, minInt(i200), -2, 0);
1829 try testRem(i200, maxInt(i200), 2, 1);
1830}
1831
1832fn testMod(comptime T: type, numerator: T, denominator: T, expected: T) !void {
1833 try expect(@mod(numerator, denominator) == expected);
1834}
1835
1836test "@mod > 128 bits" {
1837 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1838 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1839
1840 try testMod(u140, 0, maxInt(u140), 0);
1841 try testMod(u140, maxInt(u140), maxInt(u140), 0);
1842 try testMod(u140, maxInt(u140), 2, 1);
1843 try testMod(u140, (1 << 139) + 5, 1 << 70, 5);
1844 try testMod(u140, (1 << 100) + (1 << 50) + 7, 1 << 50, 7);
1845 try testMod(u200, 123, 1 << 100, 123);
1846 try testMod(u200, 1 << 120, 1 << 60, 0);
1847 try testMod(u200, maxInt(u200), 1 << 100, (1 << 100) - 1);
1848
1849 try testMod(i140, 0, maxInt(i140), 0);
1850 try testMod(i140, maxInt(i140), maxInt(i140), 0);
1851 try testMod(i140, -((1 << 100) + 1), 1 << 50, (1 << 50) - 1);
1852 try testMod(i140, (1 << 100) + 1, -(1 << 50), -(1 << 50) + 1);
1853 try testMod(i140, -((1 << 100) + 1), -(1 << 50), -1);
1854 try testMod(i200, minInt(i200), 1, 0);
1855 try testMod(i200, minInt(i200), -2, 0);
1856 try testMod(i200, maxInt(i200), 2, 1);
1857}
1858
1859fn testDivFloor(comptime T: type, numerator: T, denominator: T, expected: T) !void {
1860 try expect(@divFloor(numerator, denominator) == expected);
1861}
1862
1863test "@divFloor > 128 bits" {
1864 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1865 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1866
1867 try testDivFloor(u140, 0, maxInt(u140), 0);
1868 try testDivFloor(u140, maxInt(u140), maxInt(u140), 1);
1869 try testDivFloor(u140, maxInt(u140), 2, maxInt(u140) >> 1);
1870 try testDivFloor(u140, (1 << 139) + 5, 1 << 70, 1 << 69);
1871 try testDivFloor(u140, (1 << 100) + (1 << 50) + 7, 1 << 50, (1 << 50) + 1);
1872 try testDivFloor(u200, 123, 1 << 100, 0);
1873 try testDivFloor(u200, 1 << 120, 1 << 60, 1 << 60);
1874 try testDivFloor(u200, maxInt(u200), 1 << 100, (1 << 100) - 1);
1875
1876 try testDivFloor(i140, 0, maxInt(i140), 0);
1877 try testDivFloor(i140, maxInt(i140), maxInt(i140), 1);
1878 try testDivFloor(i140, -((1 << 100) + 1), 1 << 50, -(1 << 50) - 1);
1879 try testDivFloor(i140, (1 << 100) + 1, -(1 << 50), -(1 << 50) - 1);
1880 try testDivFloor(i140, -((1 << 100) + 1), -(1 << 50), 1 << 50);
1881 try testDivFloor(i200, -3, 2, -2);
1882 try testDivFloor(i200, minInt(i200), 1, minInt(i200));
1883 try testDivFloor(i200, minInt(i200), -2, 1 << 198);
1884 try testDivFloor(i200, maxInt(i200), 2, (1 << 198) - 1);
1885}
1886
1887fn testDivCeil(comptime T: type, numerator: T, denominator: T, expected: T) !void {
1888 try expect(@divCeil(numerator, denominator) == expected);
1889}
1890
1891test "@divCeil > 128 bits" {
1892 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1893 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1894
1895 try testDivCeil(u140, 0, maxInt(u140), 0);
1896 try testDivCeil(u140, maxInt(u140), maxInt(u140), 1);
1897 try testDivCeil(u140, maxInt(u140), 2, maxInt(u140) / 2 + 1);
1898 try testDivCeil(u140, (1 << 139) + 5, 1 << 70, (1 << 69) + 1);
1899 try testDivCeil(u140, (1 << 100) + (1 << 50) + 7, 1 << 50, (1 << 50) + 2);
1900 try testDivCeil(u200, 123, 1 << 100, 1);
1901 try testDivCeil(u200, 1 << 120, 1 << 60, 1 << 60);
1902 try testDivCeil(u200, maxInt(u200), 1 << 100, 1 << 100);
1903
1904 try testDivCeil(i140, 0, maxInt(i140), 0);
1905 try testDivCeil(i140, maxInt(i140), maxInt(i140), 1);
1906 try testDivCeil(i140, -((1 << 100) + 1), 1 << 50, -(1 << 50));
1907 try testDivCeil(i140, (1 << 100) + 1, -(1 << 50), -(1 << 50));
1908 try testDivCeil(i140, -((1 << 100) + 1), -(1 << 50), (1 << 50) + 1);
1909 try testDivCeil(i200, -3, 2, -1);
1910 try testDivCeil(i200, minInt(i200), 1, minInt(i200));
1911 try testDivCeil(i200, minInt(i200), -2, 1 << 198);
1912 try testDivCeil(i200, maxInt(i200), 2, 1 << 198);
1913}
1914
1915fn testDivTrunc(comptime T: type, numerator: T, denominator: T, expected: T) !void {
1916 try expect(@divTrunc(numerator, denominator) == expected);
1917}
1918
1919test "@divTrunc > 128 bits" {
1920 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1921 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1922
1923 try testDivTrunc(u140, 0, maxInt(u140), 0);
1924 try testDivTrunc(u140, maxInt(u140), maxInt(u140), 1);
1925 try testDivTrunc(u140, maxInt(u140), 2, maxInt(u140) >> 1);
1926 try testDivTrunc(u140, (1 << 139) + 5, 1 << 70, 1 << 69);
1927 try testDivTrunc(u140, (1 << 100) + (1 << 50) + 7, 1 << 50, (1 << 50) + 1);
1928 try testDivTrunc(u200, 123, 1 << 100, 0);
1929 try testDivTrunc(u200, 1 << 120, 1 << 60, 1 << 60);
1930 try testDivTrunc(u200, maxInt(u200), 1 << 100, (1 << 100) - 1);
1931
1932 try testDivTrunc(i140, 0, maxInt(i140), 0);
1933 try testDivTrunc(i140, maxInt(i140), maxInt(i140), 1);
1934 try testDivTrunc(i140, -((1 << 100) + 1), 1 << 50, -(1 << 50));
1935 try testDivTrunc(i140, (1 << 100) + 1, -(1 << 50), -(1 << 50));
1936 try testDivTrunc(i140, -((1 << 100) + 1), -(1 << 50), 1 << 50);
1937 try testDivTrunc(i200, -3, 2, -1);
1938 try testDivTrunc(i200, minInt(i200), 1, minInt(i200));
1939 try testDivTrunc(i200, minInt(i200), -2, 1 << 198);
1940 try testDivTrunc(i200, maxInt(i200), 2, (1 << 198) - 1);
1941}
1942
1943test "overflow arithmetic with u0 values" {
1944 {
1945 var a: u0 = 0;
1946 _ = &a;
1947 const ov = @addWithOverflow(a, 0);
1948 try expect(ov[1] == 0);
1949 try expect(ov[1] == 0);
1950 }
1951 {
1952 var a: u0 = 0;
1953 _ = &a;
1954 const ov = @subWithOverflow(a, 0);
1955 try expect(ov[1] == 0);
1956 try expect(ov[1] == 0);
1957 }
1958 {
1959 var a: u0 = 0;
1960 _ = &a;
1961 const ov = @mulWithOverflow(a, 0);
1962 try expect(ov[1] == 0);
1963 try expect(ov[1] == 0);
1964 }
1965 {
1966 var a: u0 = 0;
1967 _ = &a;
1968 const ov = @shlWithOverflow(a, 0);
1969 try expect(ov[1] == 0);
1970 try expect(ov[1] == 0);
1971 }
1972}
1973
1974test "allow signed integer division/remainder when values are comptime-known and positive or exact" {
1975 try expect(5 / 3 == 1);
1976 try expect(-5 / -3 == 1);
1977 try expect(-6 / 3 == -2);
1978
1979 try expect(5 % 3 == 2);
1980 try expect(-6 % 3 == 0);
1981}
1982
1983test "quad hex float literal parsing accurate" {
1984 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1985 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1986 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1987 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1988
1989 const a: f128 = 0x1.1111222233334444555566667777p+0;
1990
1991 // implied 1 is dropped, with an exponent of 0 (0x3fff) after biasing.
1992 const expected: u128 = 0x3fff1111222233334444555566667777;
1993 try expect(@as(u128, @bitCast(a)) == expected);
1994
1995 // non-normalized
1996 const b: f128 = 0x11.111222233334444555566667777p-4;
1997 try expect(@as(u128, @bitCast(b)) == expected);
1998
1999 const S = struct {
2000 fn doTheTest() !void {
2001 {
2002 var f: f128 = 0x1.2eab345678439abcdefea56782346p+5;
2003 _ = &f;
2004 try expect(@as(u128, @bitCast(f)) == 0x40042eab345678439abcdefea5678234);
2005 }
2006 {
2007 var f: f128 = 0x1.edcb34a235253948765432134674fp-1;
2008 _ = &f;
2009 try expect(@as(u128, @bitCast(f)) == 0x3ffeedcb34a235253948765432134675); // round-to-even
2010 }
2011 {
2012 var f: f128 = 0x1.353e45674d89abacc3a2ebf3ff4ffp-50;
2013 _ = &f;
2014 try expect(@as(u128, @bitCast(f)) == 0x3fcd353e45674d89abacc3a2ebf3ff50);
2015 }
2016 {
2017 var f: f128 = 0x1.ed8764648369535adf4be3214567fp-9;
2018 _ = &f;
2019 try expect(@as(u128, @bitCast(f)) == 0x3ff6ed8764648369535adf4be3214568);
2020 }
2021 const exp2ft = [_]f64{
2022 0x1.6a09e667f3bcdp-1,
2023 0x1.7a11473eb0187p-1,
2024 0x1.8ace5422aa0dbp-1,
2025 0x1.9c49182a3f090p-1,
2026 0x1.ae89f995ad3adp-1,
2027 0x1.c199bdd85529cp-1,
2028 0x1.d5818dcfba487p-1,
2029 0x1.ea4afa2a490dap-1,
2030 0x1.0000000000000p+0,
2031 0x1.0b5586cf9890fp+0,
2032 0x1.172b83c7d517bp+0,
2033 0x1.2387a6e756238p+0,
2034 0x1.306fe0a31b715p+0,
2035 0x1.3dea64c123422p+0,
2036 0x1.4bfdad5362a27p+0,
2037 0x1.5ab07dd485429p+0,
2038 0x1.8p23,
2039 0x1.62e430p-1,
2040 0x1.ebfbe0p-3,
2041 0x1.c6b348p-5,
2042 0x1.3b2c9cp-7,
2043 0x1.0p127,
2044 -0x1.0p-149,
2045 };
2046
2047 const answers = [_]u64{
2048 0x3fe6a09e667f3bcd,
2049 0x3fe7a11473eb0187,
2050 0x3fe8ace5422aa0db,
2051 0x3fe9c49182a3f090,
2052 0x3feae89f995ad3ad,
2053 0x3fec199bdd85529c,
2054 0x3fed5818dcfba487,
2055 0x3feea4afa2a490da,
2056 0x3ff0000000000000,
2057 0x3ff0b5586cf9890f,
2058 0x3ff172b83c7d517b,
2059 0x3ff2387a6e756238,
2060 0x3ff306fe0a31b715,
2061 0x3ff3dea64c123422,
2062 0x3ff4bfdad5362a27,
2063 0x3ff5ab07dd485429,
2064 0x4168000000000000,
2065 0x3fe62e4300000000,
2066 0x3fcebfbe00000000,
2067 0x3fac6b3480000000,
2068 0x3f83b2c9c0000000,
2069 0x47e0000000000000,
2070 0xb6a0000000000000,
2071 };
2072
2073 for (exp2ft, 0..) |x, i| {
2074 try expect(@as(u64, @bitCast(x)) == answers[i]);
2075 }
2076 }
2077 };
2078 try S.doTheTest();
2079 try comptime S.doTheTest();
2080}
2081
2082test "truncating shift left" {
2083 try testShlTrunc(maxInt(u16));
2084 try comptime testShlTrunc(maxInt(u16));
2085}
2086fn testShlTrunc(x: u16) !void {
2087 const shifted = x << 1;
2088 try expect(shifted == 65534);
2089}
2090
2091test "exact shift left" {
2092 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2093
2094 try testShlExact(0b00110101);
2095 try comptime testShlExact(0b00110101);
2096
2097 if (@shlExact(1, 1) != 2) @compileError("should be 2");
2098}
2099fn testShlExact(x: u8) !void {
2100 const shifted = @shlExact(x, 2);
2101 try expect(shifted == 0b11010100);
2102}
2103
2104test "exact shift right" {
2105 try testShrExact(0b10110100);
2106 try comptime testShrExact(0b10110100);
2107}
2108fn testShrExact(x: u8) !void {
2109 const shifted = @shrExact(x, 2);
2110 try expect(shifted == 0b00101101);
2111}
2112
2113test "shift left/right on u0 operand" {
2114 const S = struct {
2115 fn doTheTest() !void {
2116 var x: u0 = 0;
2117 var y: u0 = 0;
2118 _ = .{ &x, &y };
2119 try expectEqual(@as(u0, 0), x << 0);
2120 try expectEqual(@as(u0, 0), x >> 0);
2121 try expectEqual(@as(u0, 0), x << y);
2122 try expectEqual(@as(u0, 0), x >> y);
2123 try expectEqual(@as(u0, 0), @shlExact(x, 0));
2124 try expectEqual(@as(u0, 0), @shrExact(x, 0));
2125 try expectEqual(@as(u0, 0), @shlExact(x, y));
2126 try expectEqual(@as(u0, 0), @shrExact(x, y));
2127 }
2128 };
2129 try S.doTheTest();
2130 try comptime S.doTheTest();
2131}
2132
2133test "comptime float rem int" {
2134 comptime {
2135 const x = @as(f32, 1) % 2;
2136 try expect(x == 1.0);
2137 }
2138}
2139
2140test "remainder division" {
2141 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2142 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2143 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2144 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2145 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2146
2147 if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff and builtin.abi != .gnu) return error.SkipZigTest;
2148
2149 try comptime remdiv(f16);
2150 try comptime remdiv(f32);
2151 try comptime remdiv(f64);
2152 try comptime remdiv(f80);
2153 try comptime remdiv(f128);
2154 try remdiv(f16);
2155 try remdiv(f32);
2156 try remdiv(f64);
2157 try remdiv(f80);
2158 try remdiv(f128);
2159}
2160
2161fn remdiv(comptime T: type) !void {
2162 try expect(@as(T, 1) == @as(T, 1) % @as(T, 2));
2163 try remdivOne(T, 1, 1, 2);
2164
2165 try expect(@as(T, 1) == @as(T, 7) % @as(T, 3));
2166 try remdivOne(T, 1, 7, 3);
2167}
2168
2169fn remdivOne(comptime T: type, a: T, b: T, c: T) !void {
2170 try expect(a == @rem(b, c));
2171 try expect(a == @mod(b, c));
2172}
2173
2174test "float remainder division using @rem" {
2175 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2176 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2177 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2178 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2179
2180 try comptime frem(f16);
2181 try comptime frem(f32);
2182 try comptime frem(f64);
2183 try comptime frem(f80);
2184 try comptime frem(f128);
2185 try frem(f16);
2186 try frem(f32);
2187 try frem(f64);
2188 try frem(f80);
2189 try frem(f128);
2190}
2191
2192fn frem(comptime T: type) !void {
2193 const epsilon = switch (T) {
2194 f16 => 1.0,
2195 f32 => 0.001,
2196 f64 => 0.00001,
2197 f80 => 0.000001,
2198 f128 => 0.0000001,
2199 else => unreachable,
2200 };
2201
2202 try fremOne(T, 6.9, 4.0, 2.9, epsilon);
2203 try fremOne(T, -6.9, 4.0, -2.9, epsilon);
2204 try fremOne(T, -5.0, 3.0, -2.0, epsilon);
2205 try fremOne(T, 3.0, 2.0, 1.0, epsilon);
2206 try fremOne(T, 1.0, 2.0, 1.0, epsilon);
2207 try fremOne(T, 0.0, 1.0, 0.0, epsilon);
2208 try fremOne(T, -0.0, 1.0, -0.0, epsilon);
2209}
2210
2211fn fremOne(comptime T: type, a: T, b: T, c: T, epsilon: T) !void {
2212 try expect(@abs(@rem(a, b) - c) < epsilon);
2213}
2214
2215test "float modulo division using @mod" {
2216 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2217 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2218 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2219 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2220 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2221
2222 if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff and builtin.abi != .gnu) return error.SkipZigTest;
2223
2224 try comptime fmod(f16);
2225 try comptime fmod(f32);
2226 try comptime fmod(f64);
2227 try comptime fmod(f80);
2228 try comptime fmod(f128);
2229 try fmod(f16);
2230 try fmod(f32);
2231 try fmod(f64);
2232 try fmod(f80);
2233 try fmod(f128);
2234}
2235
2236fn fmod(comptime T: type) !void {
2237 const epsilon = switch (T) {
2238 f16 => 1.0,
2239 f32 => 0.001,
2240 f64 => 0.00001,
2241 f80 => 0.000001,
2242 f128 => 0.0000001,
2243 else => unreachable,
2244 };
2245
2246 try fmodOne(T, 6.9, 4.0, 2.9, epsilon);
2247 try fmodOne(T, -6.9, 4.0, 1.1, epsilon);
2248 try fmodOne(T, -5.0, 3.0, 1.0, epsilon);
2249 try fmodOne(T, 3.0, 2.0, 1.0, epsilon);
2250 try fmodOne(T, 1.0, 2.0, 1.0, epsilon);
2251 try fmodOne(T, 0.0, 1.0, 0.0, epsilon);
2252 try fmodOne(T, -0.0, 1.0, -0.0, epsilon);
2253}
2254
2255fn fmodOne(comptime T: type, a: T, b: T, c: T, epsilon: T) !void {
2256 try expect(@abs(@mod(@as(T, a), @as(T, b)) - @as(T, c)) < epsilon);
2257}
2258
2259test "@round f16" {
2260 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2261 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2262 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2263
2264 try testRound(f16, 12.0);
2265 try comptime testRound(f16, 12.0);
2266}
2267
2268test "@round f32/f64" {
2269 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2270 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2271 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2272
2273 try testRound(f64, 12.0);
2274 try comptime testRound(f64, 12.0);
2275 try testRound(f32, 12.0);
2276 try comptime testRound(f32, 12.0);
2277
2278 const x = 14.0;
2279 const y = x + 0.4;
2280 const z = @round(y);
2281 comptime assert(x == z);
2282}
2283
2284test "@round f80" {
2285 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2286 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2287 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2288 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2289
2290 try testRound(f80, 12.0);
2291 try comptime testRound(f80, 12.0);
2292}
2293
2294test "@round f128" {
2295 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2296 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2297 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2298 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2299
2300 try testRound(f128, 12.0);
2301 try comptime testRound(f128, 12.0);
2302}
2303
2304fn testRound(comptime T: type, x: T) !void {
2305 const y = x - 0.5;
2306 const z = @round(y);
2307 try expect(x == z);
2308}
2309
2310test "vector integer addition" {
2311 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2312 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2313 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2314 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2315 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2316
2317 const S = struct {
2318 fn doTheTest() !void {
2319 var a: @Vector(4, i32) = [_]i32{ 1, 2, 3, 4 };
2320 var b: @Vector(4, i32) = [_]i32{ 5, 6, 7, 8 };
2321 _ = .{ &a, &b };
2322 const result = a + b;
2323 var result_array: [4]i32 = result;
2324 const expected = [_]i32{ 6, 8, 10, 12 };
2325 try expectEqualSlices(i32, &expected, &result_array);
2326 }
2327 };
2328 try S.doTheTest();
2329 try comptime S.doTheTest();
2330}
2331
2332test "NaN comparison" {
2333 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2334 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2335 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2336 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2337
2338 try testNanEqNan(f16);
2339 try testNanEqNan(f32);
2340 try testNanEqNan(f64);
2341 try testNanEqNan(f128);
2342 try comptime testNanEqNan(f16);
2343 try comptime testNanEqNan(f32);
2344 try comptime testNanEqNan(f64);
2345 try comptime testNanEqNan(f128);
2346}
2347
2348test "NaN comparison f80" {
2349 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2350 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2351 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2352 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2353
2354 try testNanEqNan(f80);
2355 try comptime testNanEqNan(f80);
2356}
2357
2358fn testNanEqNan(comptime F: type) !void {
2359 var nan1 = math.nan(F);
2360 var nan2 = math.nan(F);
2361 _ = .{ &nan1, &nan2 };
2362 try expect(nan1 != nan2);
2363 try expect(!(nan1 == nan2));
2364 try expect(!(nan1 > nan2));
2365 try expect(!(nan1 >= nan2));
2366 try expect(!(nan1 < nan2));
2367 try expect(!(nan1 <= nan2));
2368}
2369
2370test "vector comparison" {
2371 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2372 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2373 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2374 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2375 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2376
2377 const S = struct {
2378 fn doTheTest() !void {
2379 var a: @Vector(6, i32) = [_]i32{ 1, 3, -1, 5, 7, 9 };
2380 var b: @Vector(6, i32) = [_]i32{ -1, 3, 0, 6, 10, -10 };
2381 _ = .{ &a, &b };
2382 try expect(mem.eql(bool, &@as([6]bool, a < b), &[_]bool{ false, false, true, true, true, false }));
2383 try expect(mem.eql(bool, &@as([6]bool, a <= b), &[_]bool{ false, true, true, true, true, false }));
2384 try expect(mem.eql(bool, &@as([6]bool, a == b), &[_]bool{ false, true, false, false, false, false }));
2385 try expect(mem.eql(bool, &@as([6]bool, a != b), &[_]bool{ true, false, true, true, true, true }));
2386 try expect(mem.eql(bool, &@as([6]bool, a > b), &[_]bool{ true, false, false, false, false, true }));
2387 try expect(mem.eql(bool, &@as([6]bool, a >= b), &[_]bool{ true, true, false, false, false, true }));
2388 }
2389 };
2390 try S.doTheTest();
2391 try comptime S.doTheTest();
2392}
2393
2394test "compare undefined literal with comptime_int" {
2395 var x = undefined == 1;
2396 // x is now undefined with type bool
2397 x = true;
2398 try expect(x);
2399}
2400
2401test "signed zeros are represented properly" {
2402 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2403 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2404 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2405 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2406
2407 const S = struct {
2408 fn doTheTest() !void {
2409 try testOne(f16);
2410 try testOne(f32);
2411 try testOne(f64);
2412 try testOne(f80);
2413 try testOne(f128);
2414 try testOne(c_longdouble);
2415 }
2416
2417 fn testOne(comptime T: type) !void {
2418 const ST = @Int(.unsigned, @typeInfo(T).float.bits);
2419 var as_fp_val = -@as(T, 0.0);
2420 _ = &as_fp_val;
2421 const as_uint_val: ST = @bitCast(as_fp_val);
2422 // Ensure the sign bit is set.
2423 try expect(as_uint_val >> (@typeInfo(T).float.bits - 1) == 1);
2424 }
2425 };
2426
2427 try S.doTheTest();
2428 try comptime S.doTheTest();
2429}
2430
2431test "absFloat" {
2432 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2433 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2434
2435 try testAbsFloat();
2436 try comptime testAbsFloat();
2437}
2438fn testAbsFloat() !void {
2439 try testAbsFloatOne(-10.05, 10.05);
2440 try testAbsFloatOne(10.05, 10.05);
2441}
2442fn testAbsFloatOne(in: f32, out: f32) !void {
2443 try expect(@abs(@as(f32, in)) == @as(f32, out));
2444}
2445
2446test "mod lazy values" {
2447 {
2448 const X = struct { x: u32 };
2449 const x = @sizeOf(X);
2450 const y = 1 % x;
2451 _ = y;
2452 }
2453 {
2454 const X = struct { x: u32 };
2455 const x = @sizeOf(X);
2456 const y = x % 1;
2457 _ = y;
2458 }
2459}
2460
2461test "@clz works on both vector and scalar inputs" {
2462 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2463 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2464 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2465 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2466 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2467
2468 var x: u32 = 0x1;
2469 _ = &x;
2470 var y: @Vector(4, u32) = [_]u32{ 0x1, 0x1, 0x1, 0x1 };
2471 _ = &y;
2472 const a = @clz(x);
2473 const b = @clz(y);
2474 try std.testing.expectEqual(@as(u6, 31), a);
2475 try std.testing.expectEqual([_]u6{ 31, 31, 31, 31 }, b);
2476}
2477
2478test "runtime comparison to NaN is comptime-known" {
2479 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2480 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2481 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2482 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2483
2484 const S = struct {
2485 fn doTheTest(comptime F: type, x: F) void {
2486 const nan = math.nan(F);
2487 if (!(nan != x)) comptime unreachable;
2488 if (nan == x) comptime unreachable;
2489 if (nan > x) comptime unreachable;
2490 if (nan < x) comptime unreachable;
2491 if (nan >= x) comptime unreachable;
2492 if (nan <= x) comptime unreachable;
2493 }
2494 };
2495
2496 S.doTheTest(f16, 123.0);
2497 S.doTheTest(f32, 123.0);
2498 S.doTheTest(f64, 123.0);
2499 S.doTheTest(f128, 123.0);
2500 comptime S.doTheTest(f16, 123.0);
2501 comptime S.doTheTest(f32, 123.0);
2502 comptime S.doTheTest(f64, 123.0);
2503 comptime S.doTheTest(f128, 123.0);
2504}
2505
2506test "runtime int comparison to inf is comptime-known" {
2507 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2508 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2509 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2510 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2511
2512 const S = struct {
2513 fn doTheTest(comptime F: type, x: u32) void {
2514 const inf = math.inf(F);
2515 if (!(inf != x)) comptime unreachable;
2516 if (inf == x) comptime unreachable;
2517 if (x > inf) comptime unreachable;
2518 if (x >= inf) comptime unreachable;
2519 if (!(x < inf)) comptime unreachable;
2520 if (!(x <= inf)) comptime unreachable;
2521 }
2522 };
2523
2524 S.doTheTest(f16, 123);
2525 S.doTheTest(f32, 123);
2526 S.doTheTest(f64, 123);
2527 S.doTheTest(f128, 123);
2528 comptime S.doTheTest(f16, 123);
2529 comptime S.doTheTest(f32, 123);
2530 comptime S.doTheTest(f64, 123);
2531 comptime S.doTheTest(f128, 123);
2532}
2533
2534test "float divide by zero" {
2535 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2536 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2537 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2538 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2539
2540 if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff and builtin.abi != .gnu) return error.SkipZigTest;
2541
2542 const S = struct {
2543 fn doTheTest(comptime F: type, zero: F, one: F) !void {
2544 try expect(math.isPositiveInf(@divTrunc(one, zero)));
2545 try expect(math.isPositiveInf(@divFloor(one, zero)));
2546
2547 try expect(math.isNan(@rem(one, zero)));
2548 try expect(math.isNan(@mod(one, zero)));
2549 }
2550 };
2551
2552 try S.doTheTest(f16, 0, 1);
2553 comptime S.doTheTest(f16, 0, 1) catch unreachable;
2554
2555 try S.doTheTest(f32, 0, 1);
2556 comptime S.doTheTest(f32, 0, 1) catch unreachable;
2557
2558 try S.doTheTest(f64, 0, 1);
2559 comptime S.doTheTest(f64, 0, 1) catch unreachable;
2560
2561 try S.doTheTest(f80, 0, 1);
2562 comptime S.doTheTest(f80, 0, 1) catch unreachable;
2563
2564 try S.doTheTest(f128, 0, 1);
2565 comptime S.doTheTest(f128, 0, 1) catch unreachable;
2566}
2567
2568test "partially-runtime integer vector division would be illegal if vector elements were reordered" {
2569 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2570 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2571 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2572 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2573 if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest;
2574
2575 var lhs: @Vector(2, i8) = .{ -128, 5 };
2576 const rhs: @Vector(2, i8) = .{ 1, -1 };
2577
2578 const expected: @Vector(2, i8) = .{ -128, -5 };
2579
2580 lhs = lhs; // suppress error
2581
2582 const trunc = @divTrunc(lhs, rhs);
2583 try expect(trunc[0] == expected[0]);
2584 try expect(trunc[1] == expected[1]);
2585
2586 const floor = @divFloor(lhs, rhs);
2587 try expect(floor[0] == expected[0]);
2588 try expect(floor[1] == expected[1]);
2589
2590 const exact = @divExact(lhs, rhs);
2591 try expect(exact[0] == expected[0]);
2592 try expect(exact[1] == expected[1]);
2593}
2594
2595test "float vector division of comptime zero by runtime nan is nan" {
2596 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2597 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2598 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2599 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2600
2601 const ct_zero: @Vector(1, f32) = .{0};
2602 var rt_nan: @Vector(1, f32) = .{math.nan(f32)};
2603
2604 rt_nan = rt_nan; // suppress error
2605
2606 try expect(math.isNan((@divTrunc(ct_zero, rt_nan))[0]));
2607 try expect(math.isNan((@divFloor(ct_zero, rt_nan))[0]));
2608 try expect(math.isNan((ct_zero / rt_nan)[0]));
2609}
2610
2611test "float vector multiplication of comptime zero by runtime nan is nan" {
2612 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
2613 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2614 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2615 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2616
2617 const ct_zero: @Vector(1, f32) = .{0};
2618 var rt_nan: @Vector(1, f32) = .{math.nan(f32)};
2619
2620 rt_nan = rt_nan; // suppress error
2621
2622 try expect(math.isNan((ct_zero * rt_nan)[0]));
2623 try expect(math.isNan((rt_nan * ct_zero)[0]));
2624}
2625
2626test "comptime float vector division of zero by nan is nan" {
2627 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2628 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2629 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2630
2631 const ct_zero: @Vector(1, f32) = .{0};
2632 const ct_nan: @Vector(1, f32) = .{math.nan(f32)};
2633
2634 comptime assert(math.isNan((@divTrunc(ct_zero, ct_nan))[0]));
2635 comptime assert(math.isNan((@divFloor(ct_zero, ct_nan))[0]));
2636 comptime assert(math.isNan((ct_zero / ct_nan)[0]));
2637}
2638
2639test "comptime float vector multiplication of zero by nan is nan" {
2640 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
2641 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
2642 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
2643
2644 const ct_zero: @Vector(1, f32) = .{0};
2645 const ct_nan: @Vector(1, f32) = .{math.nan(f32)};
2646
2647 comptime assert(math.isNan((ct_zero * ct_nan)[0]));
2648 comptime assert(math.isNan((ct_nan * ct_zero)[0]));
2649}
2650
2651test "i96 operations" {
2652 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
2653
2654 // This is coverage for some stuff used by std.Io timestamps, to catch
2655 // issues earlier than bootstrapping.
2656 const Op_i96 = union(enum) {
2657 a,
2658 b: B,
2659 c: C,
2660
2661 const B = struct {
2662 inner: struct { x: i96 },
2663 flag: bool,
2664 };
2665
2666 const C = struct {
2667 inner: struct { x: i96 },
2668 flag: bool,
2669 };
2670
2671 fn do(op: @This()) i64 {
2672 switch (op) {
2673 .a => {
2674 return std.math.minInt(i64);
2675 },
2676 .b => |b| {
2677 const x = b.inner.x;
2678 return @intCast(@divTrunc(x, 100));
2679 },
2680 .c => |c| {
2681 const a = get() catch unreachable;
2682 const b = a.x + c.inner.x;
2683 return @intCast(@divTrunc(b, 100));
2684 },
2685 }
2686 }
2687
2688 fn get() anyerror!struct { x: i96 } {
2689 return .{ .x = 999999999 };
2690 }
2691 };
2692 try expect(-9223372036854775808 == Op_i96.do(.{ .a = {} }));
2693 try expect(12345678910111213 == Op_i96.do(.{ .b = .{ .inner = .{ .x = 1234567891011121314 }, .flag = true } }));
2694 try expect(1234567891021121314 == Op_i96.do(.{ .c = .{ .inner = .{ .x = 123456789101112131415 }, .flag = true } }));
2695}
2696
2697test "zero returned from @mod matches zero in switch" {
2698 try expect(switch (@mod(-2, 2)) {
2699 0 => true,
2700 else => false,
2701 });
2702}