authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-02-13 11:59:14-07:00
committergravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-02-13 13:28:08-07:00
logc586e3ba1bbc7784aee22bf96f69b8003611112a
treee6001749749e881f079ab3693bab2b3fa98a2b1a
parent7b72fc6bbc5554643bc27933310899e32783b81b

Add additional tests for `@bitCast`


2 files changed, 119 insertions(+), 98 deletions(-)

lib/std/math/big/int_test.zig+91
......@@ -2550,6 +2550,43 @@ test "big int conversion read twos complement with padding" {
25502550 try testing.expect(std.mem.eql(u8, buffer1, &[_]u8{ 0xff, 0xff, 0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf3 }));
25512551}
25522552
2553test "big int write twos complement +/- zero" {
2554 var a = try Managed.initSet(testing.allocator, 0x0);
2555 defer a.deinit();
2556 var m = a.toMutable();
2557
2558 var buffer1 = try testing.allocator.alloc(u8, 16);
2559 defer testing.allocator.free(buffer1);
2560 @memset(buffer1.ptr, 0xaa, buffer1.len);
2561
2562 var bit_count: usize = 0;
2563
2564 // Test zero
2565
2566 m.toConst().writeTwosComplement(buffer1, bit_count, 13, .Little);
2567 try testing.expect(std.mem.eql(u8, buffer1, &(([_]u8{0} ** 13) ++ ([_]u8{0xaa} ** 3))));
2568 m.toConst().writeTwosComplement(buffer1, bit_count, 13, .Big);
2569 try testing.expect(std.mem.eql(u8, buffer1, &(([_]u8{0} ** 13) ++ ([_]u8{0xaa} ** 3))));
2570 m.toConst().writeTwosComplement(buffer1, bit_count, 16, .Little);
2571 try testing.expect(std.mem.eql(u8, buffer1, &(([_]u8{0} ** 16))));
2572 m.toConst().writeTwosComplement(buffer1, bit_count, 16, .Big);
2573 try testing.expect(std.mem.eql(u8, buffer1, &(([_]u8{0} ** 16))));
2574
2575 @memset(buffer1.ptr, 0xaa, buffer1.len);
2576 m.positive = false;
2577
2578 // Test negative zero
2579
2580 m.toConst().writeTwosComplement(buffer1, bit_count, 13, .Little);
2581 try testing.expect(std.mem.eql(u8, buffer1, &(([_]u8{0} ** 13) ++ ([_]u8{0xaa} ** 3))));
2582 m.toConst().writeTwosComplement(buffer1, bit_count, 13, .Big);
2583 try testing.expect(std.mem.eql(u8, buffer1, &(([_]u8{0} ** 13) ++ ([_]u8{0xaa} ** 3))));
2584 m.toConst().writeTwosComplement(buffer1, bit_count, 16, .Little);
2585 try testing.expect(std.mem.eql(u8, buffer1, &(([_]u8{0} ** 16))));
2586 m.toConst().writeTwosComplement(buffer1, bit_count, 16, .Big);
2587 try testing.expect(std.mem.eql(u8, buffer1, &(([_]u8{0} ** 16))));
2588}
2589
25532590test "big int conversion write twos complement with padding" {
25542591 var a = try Managed.initSet(testing.allocator, 0x01_ffffffff_ffffffff_ffffffff);
25552592 defer a.deinit();
......@@ -2564,6 +2601,8 @@ test "big int conversion write twos complement with padding" {
25642601 var bit_count: usize = 12 * 8 + 1;
25652602 var buffer: []const u8 = undefined;
25662603
2604 // Test 0x01_02030405_06070809_0a0b0c0d
2605
25672606 buffer = &[_]u8{ 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0xb };
25682607 m.readTwosComplement(buffer, bit_count, 13, .Little, .unsigned);
25692608 try testing.expect(m.toConst().orderAgainstScalar(0x01_02030405_06070809_0a0b0c0d) == .eq);
......@@ -2582,6 +2621,8 @@ test "big int conversion write twos complement with padding" {
25822621
25832622 bit_count = 12 * 8 + 2;
25842623
2624 // Test -0x01_02030405_06070809_0a0b0c0d
2625
25852626 buffer = &[_]u8{ 0xf3, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0x02 };
25862627 m.readTwosComplement(buffer, bit_count, 13, .Little, .signed);
25872628 try testing.expect(m.toConst().orderAgainstScalar(-0x01_02030405_06070809_0a0b0c0d) == .eq);
......@@ -2597,4 +2638,54 @@ test "big int conversion write twos complement with padding" {
25972638 buffer = &[_]u8{ 0xaa, 0xaa, 0xaa, 0x02, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf3 };
25982639 m.readTwosComplement(buffer, bit_count, 16, .Big, .signed);
25992640 try testing.expect(m.toConst().orderAgainstScalar(-0x01_02030405_06070809_0a0b0c0d) == .eq);
2641
2642 // Test 0
2643
2644 buffer = &([_]u8{0} ** 16);
2645 m.readTwosComplement(buffer, bit_count, 13, .Little, .unsigned);
2646 try testing.expect(m.toConst().orderAgainstScalar(0x0) == .eq);
2647 m.readTwosComplement(buffer, bit_count, 13, .Big, .unsigned);
2648 try testing.expect(m.toConst().orderAgainstScalar(0x0) == .eq);
2649 m.readTwosComplement(buffer, bit_count, 16, .Little, .unsigned);
2650 try testing.expect(m.toConst().orderAgainstScalar(0x0) == .eq);
2651 m.readTwosComplement(buffer, bit_count, 16, .Big, .unsigned);
2652 try testing.expect(m.toConst().orderAgainstScalar(0x0) == .eq);
2653
2654 bit_count = 0;
2655 buffer = &([_]u8{0xaa} ** 16);
2656 m.readTwosComplement(buffer, bit_count, 13, .Little, .unsigned);
2657 try testing.expect(m.toConst().orderAgainstScalar(0x0) == .eq);
2658 m.readTwosComplement(buffer, bit_count, 13, .Big, .unsigned);
2659 try testing.expect(m.toConst().orderAgainstScalar(0x0) == .eq);
2660 m.readTwosComplement(buffer, bit_count, 16, .Little, .unsigned);
2661 try testing.expect(m.toConst().orderAgainstScalar(0x0) == .eq);
2662 m.readTwosComplement(buffer, bit_count, 16, .Big, .unsigned);
2663 try testing.expect(m.toConst().orderAgainstScalar(0x0) == .eq);
2664}
2665
2666test "big int conversion write twos complement zero" {
2667 var a = try Managed.initSet(testing.allocator, 0x01_ffffffff_ffffffff_ffffffff);
2668 defer a.deinit();
2669
2670 var m = a.toMutable();
2671
2672 // readTwosComplement:
2673 // (1) should not read beyond buffer[0..abi_size]
2674 // (2) should correctly interpret bytes based on the provided endianness
2675 // (3) should ignore any bits from bit_count to 8 * abi_size
2676
2677 var bit_count: usize = 12 * 8 + 1;
2678 var buffer: []const u8 = undefined;
2679
2680 buffer = &([_]u8{0} ** 13);
2681 m.readTwosComplement(buffer, bit_count, 13, .Little, .unsigned);
2682 try testing.expect(m.toConst().orderAgainstScalar(0x0) == .eq);
2683 m.readTwosComplement(buffer, bit_count, 13, .Big, .unsigned);
2684 try testing.expect(m.toConst().orderAgainstScalar(0x0) == .eq);
2685
2686 buffer = &([_]u8{0} ** 16);
2687 m.readTwosComplement(buffer, bit_count, 16, .Little, .unsigned);
2688 try testing.expect(m.toConst().orderAgainstScalar(0x0) == .eq);
2689 m.readTwosComplement(buffer, bit_count, 16, .Big, .unsigned);
2690 try testing.expect(m.toConst().orderAgainstScalar(0x0) == .eq);
26002691}
test/behavior/bitcast.zig+28-98
......@@ -6,123 +6,53 @@ const maxInt = std.math.maxInt;
66const minInt = std.math.minInt;
77const native_endian = builtin.target.cpu.arch.endian();
88
9test "@bitCast i32 -> u32" {
10 try testBitCast_i32_u32();
11 comptime try testBitCast_i32_u32();
12}
13
14fn testBitCast_i32_u32() !void {
15 try expect(conv_i32(-1) == maxInt(u32));
16 try expect(conv_u32(maxInt(u32)) == -1);
17 try expect(conv_u32(0x8000_0000) == minInt(i32));
18 try expect(conv_i32(minInt(i32)) == 0x8000_0000);
19}
20
21fn conv_i32(x: i32) u32 {
22 return @bitCast(u32, x);
23}
24fn conv_u32(x: u32) i32 {
25 return @bitCast(i32, x);
26}
27
28test "@bitCast i48 -> u48" {
29 try testBitCast_i48_u48();
30 comptime try testBitCast_i48_u48();
31}
32
33fn testBitCast_i48_u48() !void {
34 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
35 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
36 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
37
38 try expect(conv_i48(-1) == maxInt(u48));
39 try expect(conv_u48(maxInt(u48)) == -1);
40 try expect(conv_u48(0x8000_0000_0000) == minInt(i48));
41 try expect(conv_i48(minInt(i48)) == 0x8000_0000_0000);
42}
43
44fn conv_i48(x: i48) u48 {
45 return @bitCast(u48, x);
46}
47
48fn conv_u48(x: u48) i48 {
49 return @bitCast(i48, x);
50}
9test "@bitCast iX -> uX" {
10 const bit_values = [_]usize{ 8, 16, 32, 64 };
5111
52test "@bitCast i27 -> u27" {
53 try testBitCast_i27_u27();
54 comptime try testBitCast_i27_u27();
12 inline for (bit_values) |bits| {
13 try testBitCast(bits);
14 comptime try testBitCast(bits);
15 }
5516}
5617
57fn testBitCast_i27_u27() !void {
18test "@bitCast iX -> uX exotic integers" {
5819 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
5920 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
6021 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
6122
62 try expect(conv_i27(-1) == maxInt(u27));
63 try expect(conv_u27(maxInt(u27)) == -1);
64 try expect(conv_u27(0x400_0000) == minInt(i27));
65 try expect(conv_i27(minInt(i27)) == 0x400_0000);
66}
67
68fn conv_i27(x: i27) u27 {
69 return @bitCast(u27, x);
70}
71
72fn conv_u27(x: u27) i27 {
73 return @bitCast(i27, x);
74}
75
76test "@bitCast i512 -> u512" {
77 try testBitCast_i512_u512();
78 comptime try testBitCast_i512_u512();
79}
80
81fn testBitCast_i512_u512() !void {
82 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
83 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
84 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
23 const bit_values = [_]usize{ 1, 48, 27, 512, 493, 293, 125, 204, 112 };
8524
86 try expect(conv_i512(-1) == maxInt(u512));
87 try expect(conv_u512(maxInt(u512)) == -1);
88 try expect(conv_u512(@as(u512, 1) << 511) == minInt(i512));
89 try expect(conv_i512(minInt(i512)) == (@as(u512, 1) << 511));
25 inline for (bit_values) |bits| {
26 try testBitCast(bits);
27 comptime try testBitCast(bits);
28 }
9029}
9130
92fn conv_i512(x: i512) u512 {
93 return @bitCast(u512, x);
94}
31fn testBitCast(comptime N: usize) !void {
32 const iN = std.meta.Int(.signed, N);
33 const uN = std.meta.Int(.unsigned, N);
9534
96fn conv_u512(x: u512) i512 {
97 return @bitCast(i512, x);
98}
35 try expect(conv_iN(N, -1) == maxInt(uN));
36 try expect(conv_uN(N, maxInt(uN)) == -1);
9937
100test "bitcast result to _" {
101 _ = @bitCast(u8, @as(i8, 1));
102}
38 try expect(conv_iN(N, maxInt(iN)) == maxInt(iN));
39 try expect(conv_uN(N, maxInt(iN)) == maxInt(iN));
10340
104test "@bitCast i493 -> u493" {
105 try testBitCast_i493_u493();
106 comptime try testBitCast_i493_u493();
107}
41 try expect(conv_uN(N, 1 << (N - 1)) == minInt(iN));
42 try expect(conv_iN(N, minInt(iN)) == (1 << (N - 1)));
10843
109fn testBitCast_i493_u493() !void {
110 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
111 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
112 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
44 try expect(conv_uN(N, 0) == 0);
45 try expect(conv_iN(N, 0) == 0);
11346
114 try expect(conv_i493(-1) == maxInt(u493));
115 try expect(conv_u493(maxInt(u493)) == -1);
116 try expect(conv_u493(@as(u493, 1) << 492) == minInt(i493));
117 try expect(conv_i493(minInt(i493)) == (@as(u493, 1) << 492));
47 try expect(conv_iN(N, -0) == 0);
11848}
11949
120fn conv_i493(x: i493) u493 {
121 return @bitCast(u493, x);
50fn conv_iN(comptime N: usize, x: std.meta.Int(.signed, N)) std.meta.Int(.unsigned, N) {
51 return @bitCast(std.meta.Int(.unsigned, N), x);
12252}
12353
124fn conv_u493(x: u493) i493 {
125 return @bitCast(i493, x);
54fn conv_uN(comptime N: usize, x: std.meta.Int(.unsigned, N)) std.meta.Int(.signed, N) {
55 return @bitCast(std.meta.Int(.signed, N), x);
12656}
12757
12858test "nested bitcast" {