| ... | ... | @@ -17,12 +17,20 @@ pub fn log2(x: anytype) @TypeOf(x) { |
| 17 | 17 | }, |
| 18 | 18 | .Float => return @log2(x), |
| 19 | 19 | .ComptimeInt => comptime { |
| 20 | | var result = 0; |
| 21 | 20 | var x_shifted = x; |
| 22 | | while (b: { |
| 23 | | x_shifted >>= 1; |
| 24 | | break :b x_shifted != 0; |
| 25 | | }) : (result += 1) {} |
| 21 | // First, calculate floorPowerOfTwo(x) |
| 22 | var shift_amt = 1; |
| 23 | while (x_shifted >> (shift_amt << 1) != 0) shift_amt <<= 1; |
| 24 | |
| 25 | // Answer is in the range [shift_amt, 2 * shift_amt - 1] |
| 26 | // We can find it in O(log(N)) using binary search. |
| 27 | var result = 0; |
| 28 | while (shift_amt != 0) : (shift_amt >>= 1) { |
| 29 | if (x_shifted >> shift_amt != 0) { |
| 30 | x_shifted >>= shift_amt; |
| 31 | result += shift_amt; |
| 32 | } |
| 33 | } |
| 26 | 34 | return result; |
| 27 | 35 | }, |
| 28 | 36 | .Int => |IntType| switch (IntType.signedness) { |
| ... | ... | @@ -36,4 +44,10 @@ pub fn log2(x: anytype) @TypeOf(x) { |
| 36 | 44 | test "log2" { |
| 37 | 45 | try expect(log2(@as(f32, 0.2)) == @log2(0.2)); |
| 38 | 46 | try expect(log2(@as(f64, 0.2)) == @log2(0.2)); |
| 47 | comptime { |
| 48 | try expect(log2(1) == 0); |
| 49 | try expect(log2(15) == 3); |
| 50 | try expect(log2(16) == 4); |
| 51 | try expect(log2(1 << 4073) == 4073); |
| 52 | } |
| 39 | 53 | } |