diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig index e3dcb8d71d..29c1423a14 100644 --- a/lib/std/math/big/int.zig +++ b/lib/std/math/big/int.zig @@ -2670,6 +2670,11 @@ pub const Const = struct { } return @min(result, bits); } + + /// Calculate the base 2 logarithm, rounded down. + pub fn log2(a: Const) Limb { + return a.limbs.len * @bitSizeOf(Limb) - 1 - @clz(a.limbs[a.limbs.len - 1]); + } }; /// An arbitrary-precision big integer along with an allocator which manages the memory. diff --git a/lib/std/math/big/int_test.zig b/lib/std/math/big/int_test.zig index 34dec3fdde..2c2aeb9df7 100644 --- a/lib/std/math/big/int_test.zig +++ b/lib/std/math/big/int_test.zig @@ -4072,3 +4072,20 @@ test "ctz" { try testing.expectEqual(0, limb_max_squared.ctz(@bitSizeOf(Limb) * 2)); try testing.expectEqual(0, limb_max_squared.ctz(@bitSizeOf(Limb) * 2 + 1)); } + +test "log2" { + var a = try Managed.init(testing.allocator); + defer a.deinit(); + + try a.setString(2, "1"); + try testing.expectEqual(0, a.toConst().log2()); + + try a.setString(2, "1111011"); + try testing.expectEqual(6, a.toConst().log2()); + + try a.setString(2, "10100111011101010"); + try testing.expectEqual(16, a.toConst().log2()); + + try a.setString(16, "a22d71c87a9ce406da4f5895f9f3cc3d603192baf6c8a2b5c32649d0465bf188fe799b3618085e49d71bdaec01"); + try testing.expectEqual(359, a.toConst().log2()); +}