From f516e2c5b1d0e073d9ab4cd417aeb21f6cdf4a99 Mon Sep 17 00:00:00 2001 From: Cody Tapscott Date: Fri, 11 Feb 2022 09:24:08 -0700 Subject: Simplify implementation of floorPowerOfTwo in std.math --- lib/std/math.zig | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'lib/std/math.zig') diff --git a/lib/std/math.zig b/lib/std/math.zig index 4b8bcf2287..71cb5a184c 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -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). -- cgit v1.2.3