diff options
| author | Rekai Nyangadzayi Musuka <rekai@musuka.dev> | 2022-10-10 18:22:35 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-11 00:22:35 +0300 |
| commit | dacdc95ea24c12e2f1771f928ffa4bbd18cc3a19 (patch) | |
| tree | 9bef8812cafba9d79c9672a2beb3560a70e64755 /lib/std/math.zig | |
| parent | 02fff6fd0172502545389dcf335b173b4f951dda (diff) | |
| download | zig-dacdc95ea24c12e2f1771f928ffa4bbd18cc3a19.tar.gz zig-dacdc95ea24c12e2f1771f928ffa4bbd18cc3a19.zip | |
std/math.zig: use previous rotate code with non-power-of-two integers
Diffstat (limited to 'lib/std/math.zig')
| -rw-r--r-- | lib/std/math.zig | 32 |
1 files changed, 28 insertions, 4 deletions
diff --git a/lib/std/math.zig b/lib/std/math.zig index 18c8f555d4..2f16ecb5d8 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -598,6 +598,8 @@ test "shr" { pub fn rotr(comptime T: type, x: T, r: anytype) T { if (@typeInfo(T) == .Vector) { const C = @typeInfo(T).Vector.child; + if (C == u0) return 0; + if (@typeInfo(C).Int.signedness == .signed) { @compileError("cannot rotate signed integers"); } @@ -606,8 +608,15 @@ pub fn rotr(comptime T: type, x: T, r: anytype) T { } else if (@typeInfo(T).Int.signedness == .signed) { @compileError("cannot rotate signed integer"); } else { - const ar = @intCast(Log2Int(T), @mod(r, @typeInfo(T).Int.bits)); - return x >> ar | x << (1 +% ~ar); + if (T == u0) return 0; + + if (isPowerOfTwo(@typeInfo(T).Int.bits)) { + const ar = @intCast(Log2Int(T), @mod(r, @typeInfo(T).Int.bits)); + return x >> ar | x << (1 +% ~ar); + } else { + const ar = @mod(r, @typeInfo(T).Int.bits); + return shr(T, x, ar) | shl(T, x, @typeInfo(T).Int.bits - ar); + } } } @@ -618,6 +627,9 @@ test "rotr" { // https://github.com/ziglang/zig/issues/12012 return error.SkipZigTest; } + try testing.expect(rotr(u0, 0b0, @as(usize, 3)) == 0b0); + try testing.expect(rotr(u5, 0b00001, @as(usize, 0)) == 0b00001); + try testing.expect(rotr(u6, 0b000001, @as(usize, 7)) == 0b100000); try testing.expect(rotr(u8, 0b00000001, @as(usize, 0)) == 0b00000001); try testing.expect(rotr(u8, 0b00000001, @as(usize, 9)) == 0b10000000); try testing.expect(rotr(u8, 0b00000001, @as(usize, 8)) == 0b00000001); @@ -632,6 +644,8 @@ test "rotr" { pub fn rotl(comptime T: type, x: T, r: anytype) T { if (@typeInfo(T) == .Vector) { const C = @typeInfo(T).Vector.child; + if (C == u0) return 0; + if (@typeInfo(C).Int.signedness == .signed) { @compileError("cannot rotate signed integers"); } @@ -640,8 +654,15 @@ pub fn rotl(comptime T: type, x: T, r: anytype) T { } else if (@typeInfo(T).Int.signedness == .signed) { @compileError("cannot rotate signed integer"); } else { - const ar = @intCast(Log2Int(T), @mod(r, @typeInfo(T).Int.bits)); - return x << ar | x >> 1 +% ~ar; + if (T == u0) return 0; + + if (isPowerOfTwo(@typeInfo(T).Int.bits)) { + const ar = @intCast(Log2Int(T), @mod(r, @typeInfo(T).Int.bits)); + return x << ar | x >> 1 +% ~ar; + } else { + const ar = @mod(r, @typeInfo(T).Int.bits); + return shl(T, x, ar) | shr(T, x, @typeInfo(T).Int.bits - ar); + } } } @@ -652,6 +673,9 @@ test "rotl" { // https://github.com/ziglang/zig/issues/12012 return error.SkipZigTest; } + try testing.expect(rotl(u0, 0b0, @as(usize, 3)) == 0b0); + try testing.expect(rotl(u5, 0b00001, @as(usize, 0)) == 0b00001); + try testing.expect(rotl(u6, 0b000001, @as(usize, 7)) == 0b000010); try testing.expect(rotl(u8, 0b00000001, @as(usize, 0)) == 0b00000001); try testing.expect(rotl(u8, 0b00000001, @as(usize, 9)) == 0b00000010); try testing.expect(rotl(u8, 0b00000001, @as(usize, 8)) == 0b00000001); |
