|
const std = @import("../std.zig"); const builtin = @import("builtin"); const math = std.math; const expect = std.testing.expect; |
log2() Returns the base-2 logarithm of x. |
pub fn log2(x: anytype) @TypeOf(x) { const T = @TypeOf(x); switch (@typeInfo(T)) { .ComptimeFloat => { return @as(comptime_float, @log2(x)); }, .Float => return @log2(x), .ComptimeInt => comptime { var x_shifted = x; // First, calculate floorPowerOfTwo(x) var shift_amt = 1; while (x_shifted >> (shift_amt << 1) != 0) shift_amt <<= 1; // Answer is in the range [shift_amt, 2 * shift_amt - 1] // We can find it in O(log(N)) using binary search. var result = 0; while (shift_amt != 0) : (shift_amt >>= 1) { if (x_shifted >> shift_amt != 0) { x_shifted >>= shift_amt; result += shift_amt; } } return result; }, .Int => |IntType| switch (IntType.signedness) { .signed => @compileError("log2 not implemented for signed integers"), .unsigned => return math.log2_int(T, x), }, else => @compileError("log2 not implemented for " ++ @typeName(T)), } } |
Test:log2 |
test "log2" { // https://github.com/ziglang/zig/issues/13703 if (builtin.cpu.arch == .aarch64 and builtin.os.tag == .windows) return error.SkipZigTest; try expect(log2(@as(f32, 0.2)) == @log2(0.2)); try expect(log2(@as(f64, 0.2)) == @log2(0.2)); comptime { try expect(log2(1) == 0); try expect(log2(15) == 3); try expect(log2(16) == 4); try expect(log2(1 << 4073) == 4073); } } |
Generated by zstd-browse2 on 2023-11-04 14:12:22 -0400. |