Simplify implementation of floorPowerOfTwo in std.math

This commit is contained in:
Cody Tapscott 2022-02-11 09:24:08 -07:00 committed by Veikka Tuominen
parent 3bbe6a28e0
commit f516e2c5b1

View File

@ -1045,14 +1045,9 @@ pub fn isPowerOfTwo(v: anytype) bool {
/// Returns the nearest power of two less than or equal to value, or
/// zero if value is less than or equal to zero.
pub fn floorPowerOfTwo(comptime T: type, value: T) T {
var x = value;
comptime var i = 1;
inline while (@typeInfo(T).Int.bits > i) : (i *= 2) {
x |= (x >> i);
}
return x - (x >> 1);
const uT = std.meta.Int(.unsigned, @typeInfo(T).Int.bits);
if (value <= 0) return 0;
return @as(T, 1) << log2_int(uT, @intCast(uT, value));
}
test "math.floorPowerOfTwo" {
@ -1064,9 +1059,15 @@ fn testFloorPowerOfTwo() !void {
try testing.expect(floorPowerOfTwo(u32, 63) == 32);
try testing.expect(floorPowerOfTwo(u32, 64) == 64);
try testing.expect(floorPowerOfTwo(u32, 65) == 64);
try testing.expect(floorPowerOfTwo(u32, 0) == 0);
try testing.expect(floorPowerOfTwo(u4, 7) == 4);
try testing.expect(floorPowerOfTwo(u4, 8) == 8);
try testing.expect(floorPowerOfTwo(u4, 9) == 8);
try testing.expect(floorPowerOfTwo(u4, 0) == 0);
try testing.expect(floorPowerOfTwo(i4, 7) == 4);
try testing.expect(floorPowerOfTwo(i4, -8) == 0);
try testing.expect(floorPowerOfTwo(i4, -1) == 0);
try testing.expect(floorPowerOfTwo(i4, 0) == 0);
}
/// Returns the next power of two (if the value is not already a power of two).