mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
std/math.zig: use previous rotate code with non-power-of-two integers
This commit is contained in:
parent
02fff6fd01
commit
dacdc95ea2
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user