diff --git a/lib/std/math/big/int.zig b/lib/std/math/big/int.zig index e3dcb8d71dbb664df58284ab2e28b887110f0dd7..29c1423a1446184dd4c8ba99a623b56afd03fac8 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 34dec3fdde9d106d90b8ffb3dbfec469eb2701af..2c2aeb9df71f86e0f52f39557204a67a6354c315 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()); +}