| ... | ... | @@ -1045,14 +1045,9 @@ pub fn isPowerOfTwo(v: anytype) bool { |
| 1045 | 1045 | /// Returns the nearest power of two less than or equal to value, or |
| 1046 | 1046 | /// zero if value is less than or equal to zero. |
| 1047 | 1047 | pub fn floorPowerOfTwo(comptime T: type, value: T) T { |
| 1048 | | var x = value; |
| 1049 | | |
| 1050 | | comptime var i = 1; |
| 1051 | | inline while (@typeInfo(T).Int.bits > i) : (i *= 2) { |
| 1052 | | x |= (x >> i); |
| 1053 | | } |
| 1054 | | |
| 1055 | | return x - (x >> 1); |
| 1048 | const uT = std.meta.Int(.unsigned, @typeInfo(T).Int.bits); |
| 1049 | if (value <= 0) return 0; |
| 1050 | return @as(T, 1) << log2_int(uT, @intCast(uT, value)); |
| 1056 | 1051 | } |
| 1057 | 1052 | |
| 1058 | 1053 | test "math.floorPowerOfTwo" { |
| ... | ... | @@ -1064,9 +1059,15 @@ fn testFloorPowerOfTwo() !void { |
| 1064 | 1059 | try testing.expect(floorPowerOfTwo(u32, 63) == 32); |
| 1065 | 1060 | try testing.expect(floorPowerOfTwo(u32, 64) == 64); |
| 1066 | 1061 | try testing.expect(floorPowerOfTwo(u32, 65) == 64); |
| 1062 | try testing.expect(floorPowerOfTwo(u32, 0) == 0); |
| 1067 | 1063 | try testing.expect(floorPowerOfTwo(u4, 7) == 4); |
| 1068 | 1064 | try testing.expect(floorPowerOfTwo(u4, 8) == 8); |
| 1069 | 1065 | try testing.expect(floorPowerOfTwo(u4, 9) == 8); |
| 1066 | try testing.expect(floorPowerOfTwo(u4, 0) == 0); |
| 1067 | try testing.expect(floorPowerOfTwo(i4, 7) == 4); |
| 1068 | try testing.expect(floorPowerOfTwo(i4, -8) == 0); |
| 1069 | try testing.expect(floorPowerOfTwo(i4, -1) == 0); |
| 1070 | try testing.expect(floorPowerOfTwo(i4, 0) == 0); |
| 1070 | 1071 | } |
| 1071 | 1072 | |
| 1072 | 1073 | /// Returns the next power of two (if the value is not already a power of two). |