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