@@ -3332,3 +3332,227 @@ test "(BigInt) negative" {
33323332 try testing .expect (mem .eql (u8 , a_fmt , "(BigInt)" ));
33333333 try testing .expect (! mem .eql (u8 , b_fmt , "(BigInt)" ));
33343334}
3335+
3336+ test "clz" {
3337+ const neg_limb_max_squared : std.math.big.int.Const = .{
3338+ .limbs = &.{ 1 , maxInt (Limb ) - 1 },
3339+ .positive = false ,
3340+ };
3341+ try testing .expect (neg_limb_max_squared .clz (@bitSizeOf (Limb ) * 2 + 1 ) == 0 );
3342+
3343+ const neg_limb_max_squared_plus_one : std.math.big.int.Const = .{
3344+ .limbs = &.{ 0 , maxInt (Limb ) - 1 },
3345+ .positive = false ,
3346+ };
3347+ try testing .expect (neg_limb_max_squared_plus_one .clz (@bitSizeOf (Limb ) * 2 + 1 ) == 0 );
3348+
3349+ const neg_limb_msb_squared : std.math.big.int.Const = .{
3350+ .limbs = &.{ 0 , 1 << @bitSizeOf (Limb ) - 2 },
3351+ .positive = false ,
3352+ };
3353+ try testing .expect (neg_limb_msb_squared .clz (@bitSizeOf (Limb ) * 2 ) == 0 );
3354+ try testing .expect (neg_limb_msb_squared .clz (@bitSizeOf (Limb ) * 2 + 1 ) == 0 );
3355+
3356+ const neg_limb_max : std.math.big.int.Const = .{
3357+ .limbs = &.{maxInt (Limb )},
3358+ .positive = false ,
3359+ };
3360+ try testing .expect (neg_limb_max .clz (@bitSizeOf (Limb ) + 1 ) == 0 );
3361+ try testing .expect (neg_limb_max .clz (@bitSizeOf (Limb ) * 2 - 1 ) == 0 );
3362+ try testing .expect (neg_limb_max .clz (@bitSizeOf (Limb ) * 2 ) == 0 );
3363+ try testing .expect (neg_limb_max .clz (@bitSizeOf (Limb ) * 2 + 1 ) == 0 );
3364+
3365+ const neg_limb_msb : std.math.big.int.Const = .{
3366+ .limbs = &.{1 << @bitSizeOf (Limb ) - 1 },
3367+ .positive = false ,
3368+ };
3369+ try testing .expect (neg_limb_msb .clz (@bitSizeOf (Limb )) == 0 );
3370+ try testing .expect (neg_limb_msb .clz (@bitSizeOf (Limb ) + 1 ) == 0 );
3371+ try testing .expect (neg_limb_msb .clz (@bitSizeOf (Limb ) * 2 - 1 ) == 0 );
3372+ try testing .expect (neg_limb_msb .clz (@bitSizeOf (Limb ) * 2 ) == 0 );
3373+ try testing .expect (neg_limb_msb .clz (@bitSizeOf (Limb ) * 2 + 1 ) == 0 );
3374+
3375+ const neg_one : std.math.big.int.Const = .{
3376+ .limbs = &.{1 },
3377+ .positive = false ,
3378+ };
3379+ try testing .expect (neg_one .clz (@bitSizeOf (Limb )) == 0 );
3380+ try testing .expect (neg_one .clz (@bitSizeOf (Limb ) + 1 ) == 0 );
3381+ try testing .expect (neg_one .clz (@bitSizeOf (Limb ) * 2 - 1 ) == 0 );
3382+ try testing .expect (neg_one .clz (@bitSizeOf (Limb ) * 2 ) == 0 );
3383+ try testing .expect (neg_one .clz (@bitSizeOf (Limb ) * 2 + 1 ) == 0 );
3384+
3385+ const zero : std.math.big.int.Const = .{
3386+ .limbs = &.{0 },
3387+ .positive = true ,
3388+ };
3389+ try testing .expect (zero .clz (@bitSizeOf (Limb )) == @bitSizeOf (Limb ));
3390+ try testing .expect (zero .clz (@bitSizeOf (Limb ) + 1 ) == @bitSizeOf (Limb ) + 1 );
3391+ try testing .expect (zero .clz (@bitSizeOf (Limb ) * 2 - 1 ) == @bitSizeOf (Limb ) * 2 - 1 );
3392+ try testing .expect (zero .clz (@bitSizeOf (Limb ) * 2 ) == @bitSizeOf (Limb ) * 2 );
3393+ try testing .expect (zero .clz (@bitSizeOf (Limb ) * 2 + 1 ) == @bitSizeOf (Limb ) * 2 + 1 );
3394+
3395+ const one : std.math.big.int.Const = .{
3396+ .limbs = &.{1 },
3397+ .positive = true ,
3398+ };
3399+ try testing .expect (one .clz (@bitSizeOf (Limb )) == @bitSizeOf (Limb ) - 1 );
3400+ try testing .expect (one .clz (@bitSizeOf (Limb ) + 1 ) == @bitSizeOf (Limb ));
3401+ try testing .expect (one .clz (@bitSizeOf (Limb ) * 2 - 1 ) == @bitSizeOf (Limb ) * 2 - 2 );
3402+ try testing .expect (one .clz (@bitSizeOf (Limb ) * 2 ) == @bitSizeOf (Limb ) * 2 - 1 );
3403+ try testing .expect (one .clz (@bitSizeOf (Limb ) * 2 + 1 ) == @bitSizeOf (Limb ) * 2 );
3404+
3405+ const limb_msb : std.math.big.int.Const = .{
3406+ .limbs = &.{1 << @bitSizeOf (Limb ) - 1 },
3407+ .positive = true ,
3408+ };
3409+ try testing .expect (limb_msb .clz (@bitSizeOf (Limb )) == 0 );
3410+ try testing .expect (limb_msb .clz (@bitSizeOf (Limb ) + 1 ) == 1 );
3411+ try testing .expect (limb_msb .clz (@bitSizeOf (Limb ) * 2 - 1 ) == @bitSizeOf (Limb ) - 1 );
3412+ try testing .expect (limb_msb .clz (@bitSizeOf (Limb ) * 2 ) == @bitSizeOf (Limb ));
3413+ try testing .expect (limb_msb .clz (@bitSizeOf (Limb ) * 2 + 1 ) == @bitSizeOf (Limb ) + 1 );
3414+
3415+ const limb_max : std.math.big.int.Const = .{
3416+ .limbs = &.{maxInt (Limb )},
3417+ .positive = true ,
3418+ };
3419+ try testing .expect (limb_max .clz (@bitSizeOf (Limb )) == 0 );
3420+ try testing .expect (limb_max .clz (@bitSizeOf (Limb ) + 1 ) == 1 );
3421+ try testing .expect (limb_max .clz (@bitSizeOf (Limb ) * 2 - 1 ) == @bitSizeOf (Limb ) - 1 );
3422+ try testing .expect (limb_max .clz (@bitSizeOf (Limb ) * 2 ) == @bitSizeOf (Limb ));
3423+ try testing .expect (limb_max .clz (@bitSizeOf (Limb ) * 2 + 1 ) == @bitSizeOf (Limb ) + 1 );
3424+
3425+ const limb_msb_squared : std.math.big.int.Const = .{
3426+ .limbs = &.{ 0 , 1 << @bitSizeOf (Limb ) - 2 },
3427+ .positive = true ,
3428+ };
3429+ try testing .expect (limb_msb_squared .clz (@bitSizeOf (Limb ) * 2 - 1 ) == 0 );
3430+ try testing .expect (limb_msb_squared .clz (@bitSizeOf (Limb ) * 2 ) == 1 );
3431+ try testing .expect (limb_msb_squared .clz (@bitSizeOf (Limb ) * 2 + 1 ) == 2 );
3432+
3433+ const limb_max_squared_minus_one : std.math.big.int.Const = .{
3434+ .limbs = &.{ 0 , maxInt (Limb ) - 1 },
3435+ .positive = true ,
3436+ };
3437+ try testing .expect (limb_max_squared_minus_one .clz (@bitSizeOf (Limb ) * 2 ) == 0 );
3438+ try testing .expect (limb_max_squared_minus_one .clz (@bitSizeOf (Limb ) * 2 + 1 ) == 1 );
3439+
3440+ const limb_max_squared : std.math.big.int.Const = .{
3441+ .limbs = &.{ 1 , maxInt (Limb ) - 1 },
3442+ .positive = true ,
3443+ };
3444+ try testing .expect (limb_max_squared .clz (@bitSizeOf (Limb ) * 2 ) == 0 );
3445+ try testing .expect (limb_max_squared .clz (@bitSizeOf (Limb ) * 2 + 1 ) == 1 );
3446+ }
3447+
3448+ test "ctz" {
3449+ const neg_limb_max_squared : std.math.big.int.Const = .{
3450+ .limbs = &.{ 1 , maxInt (Limb ) - 1 },
3451+ .positive = false ,
3452+ };
3453+ try testing .expect (neg_limb_max_squared .ctz (@bitSizeOf (Limb ) * 2 + 1 ) == 0 );
3454+
3455+ const neg_limb_max_squared_plus_one : std.math.big.int.Const = .{
3456+ .limbs = &.{ 0 , maxInt (Limb ) - 1 },
3457+ .positive = false ,
3458+ };
3459+ try testing .expect (neg_limb_max_squared_plus_one .ctz (@bitSizeOf (Limb ) * 2 + 1 ) == @bitSizeOf (Limb ) + 1 );
3460+
3461+ const neg_limb_msb_squared : std.math.big.int.Const = .{
3462+ .limbs = &.{ 0 , 1 << @bitSizeOf (Limb ) - 2 },
3463+ .positive = false ,
3464+ };
3465+ try testing .expect (neg_limb_msb_squared .ctz (@bitSizeOf (Limb ) * 2 ) == @bitSizeOf (Limb ) * 2 - 2 );
3466+ try testing .expect (neg_limb_msb_squared .ctz (@bitSizeOf (Limb ) * 2 + 1 ) == @bitSizeOf (Limb ) * 2 - 2 );
3467+
3468+ const neg_limb_max : std.math.big.int.Const = .{
3469+ .limbs = &.{maxInt (Limb )},
3470+ .positive = false ,
3471+ };
3472+ try testing .expect (neg_limb_max .ctz (@bitSizeOf (Limb ) + 1 ) == 0 );
3473+ try testing .expect (neg_limb_max .ctz (@bitSizeOf (Limb ) * 2 - 1 ) == 0 );
3474+ try testing .expect (neg_limb_max .ctz (@bitSizeOf (Limb ) * 2 ) == 0 );
3475+ try testing .expect (neg_limb_max .ctz (@bitSizeOf (Limb ) * 2 + 1 ) == 0 );
3476+
3477+ const neg_limb_msb : std.math.big.int.Const = .{
3478+ .limbs = &.{1 << @bitSizeOf (Limb ) - 1 },
3479+ .positive = false ,
3480+ };
3481+ try testing .expect (neg_limb_msb .ctz (@bitSizeOf (Limb )) == @bitSizeOf (Limb ) - 1 );
3482+ try testing .expect (neg_limb_msb .ctz (@bitSizeOf (Limb ) + 1 ) == @bitSizeOf (Limb ) - 1 );
3483+ try testing .expect (neg_limb_msb .ctz (@bitSizeOf (Limb ) * 2 - 1 ) == @bitSizeOf (Limb ) - 1 );
3484+ try testing .expect (neg_limb_msb .ctz (@bitSizeOf (Limb ) * 2 ) == @bitSizeOf (Limb ) - 1 );
3485+ try testing .expect (neg_limb_msb .ctz (@bitSizeOf (Limb ) * 2 + 1 ) == @bitSizeOf (Limb ) - 1 );
3486+
3487+ const neg_one : std.math.big.int.Const = .{
3488+ .limbs = &.{1 },
3489+ .positive = false ,
3490+ };
3491+ try testing .expect (neg_one .ctz (@bitSizeOf (Limb )) == 0 );
3492+ try testing .expect (neg_one .ctz (@bitSizeOf (Limb ) + 1 ) == 0 );
3493+ try testing .expect (neg_one .ctz (@bitSizeOf (Limb ) * 2 - 1 ) == 0 );
3494+ try testing .expect (neg_one .ctz (@bitSizeOf (Limb ) * 2 ) == 0 );
3495+ try testing .expect (neg_one .ctz (@bitSizeOf (Limb ) * 2 + 1 ) == 0 );
3496+
3497+ const zero : std.math.big.int.Const = .{
3498+ .limbs = &.{0 },
3499+ .positive = true ,
3500+ };
3501+ try testing .expect (zero .ctz (@bitSizeOf (Limb )) == @bitSizeOf (Limb ));
3502+ try testing .expect (zero .ctz (@bitSizeOf (Limb ) + 1 ) == @bitSizeOf (Limb ) + 1 );
3503+ try testing .expect (zero .ctz (@bitSizeOf (Limb ) * 2 - 1 ) == @bitSizeOf (Limb ) * 2 - 1 );
3504+ try testing .expect (zero .ctz (@bitSizeOf (Limb ) * 2 ) == @bitSizeOf (Limb ) * 2 );
3505+ try testing .expect (zero .ctz (@bitSizeOf (Limb ) * 2 + 1 ) == @bitSizeOf (Limb ) * 2 + 1 );
3506+
3507+ const one : std.math.big.int.Const = .{
3508+ .limbs = &.{1 },
3509+ .positive = true ,
3510+ };
3511+ try testing .expect (one .ctz (@bitSizeOf (Limb )) == 0 );
3512+ try testing .expect (one .ctz (@bitSizeOf (Limb ) + 1 ) == 0 );
3513+ try testing .expect (one .ctz (@bitSizeOf (Limb ) * 2 - 1 ) == 0 );
3514+ try testing .expect (one .ctz (@bitSizeOf (Limb ) * 2 ) == 0 );
3515+ try testing .expect (one .ctz (@bitSizeOf (Limb ) * 2 + 1 ) == 0 );
3516+
3517+ const limb_msb : std.math.big.int.Const = .{
3518+ .limbs = &.{1 << @bitSizeOf (Limb ) - 1 },
3519+ .positive = true ,
3520+ };
3521+ try testing .expect (limb_msb .ctz (@bitSizeOf (Limb )) == @bitSizeOf (Limb ) - 1 );
3522+ try testing .expect (limb_msb .ctz (@bitSizeOf (Limb ) + 1 ) == @bitSizeOf (Limb ) - 1 );
3523+ try testing .expect (limb_msb .ctz (@bitSizeOf (Limb ) * 2 - 1 ) == @bitSizeOf (Limb ) - 1 );
3524+ try testing .expect (limb_msb .ctz (@bitSizeOf (Limb ) * 2 ) == @bitSizeOf (Limb ) - 1 );
3525+ try testing .expect (limb_msb .ctz (@bitSizeOf (Limb ) * 2 + 1 ) == @bitSizeOf (Limb ) - 1 );
3526+
3527+ const limb_max : std.math.big.int.Const = .{
3528+ .limbs = &.{maxInt (Limb )},
3529+ .positive = true ,
3530+ };
3531+ try testing .expect (limb_max .ctz (@bitSizeOf (Limb )) == 0 );
3532+ try testing .expect (limb_max .ctz (@bitSizeOf (Limb ) + 1 ) == 0 );
3533+ try testing .expect (limb_max .ctz (@bitSizeOf (Limb ) * 2 - 1 ) == 0 );
3534+ try testing .expect (limb_max .ctz (@bitSizeOf (Limb ) * 2 ) == 0 );
3535+ try testing .expect (limb_max .ctz (@bitSizeOf (Limb ) * 2 + 1 ) == 0 );
3536+
3537+ const limb_msb_squared : std.math.big.int.Const = .{
3538+ .limbs = &.{ 0 , 1 << @bitSizeOf (Limb ) - 2 },
3539+ .positive = true ,
3540+ };
3541+ try testing .expect (limb_msb_squared .ctz (@bitSizeOf (Limb ) * 2 - 1 ) == @bitSizeOf (Limb ) * 2 - 2 );
3542+ try testing .expect (limb_msb_squared .ctz (@bitSizeOf (Limb ) * 2 ) == @bitSizeOf (Limb ) * 2 - 2 );
3543+ try testing .expect (limb_msb_squared .ctz (@bitSizeOf (Limb ) * 2 + 1 ) == @bitSizeOf (Limb ) * 2 - 2 );
3544+
3545+ const limb_max_squared_minus_one : std.math.big.int.Const = .{
3546+ .limbs = &.{ 0 , maxInt (Limb ) - 1 },
3547+ .positive = true ,
3548+ };
3549+ try testing .expect (limb_max_squared_minus_one .ctz (@bitSizeOf (Limb ) * 2 ) == @bitSizeOf (Limb ) + 1 );
3550+ try testing .expect (limb_max_squared_minus_one .ctz (@bitSizeOf (Limb ) * 2 + 1 ) == @bitSizeOf (Limb ) + 1 );
3551+
3552+ const limb_max_squared : std.math.big.int.Const = .{
3553+ .limbs = &.{ 1 , maxInt (Limb ) - 1 },
3554+ .positive = true ,
3555+ };
3556+ try testing .expect (limb_max_squared .ctz (@bitSizeOf (Limb ) * 2 ) == 0 );
3557+ try testing .expect (limb_max_squared .ctz (@bitSizeOf (Limb ) * 2 + 1 ) == 0 );
3558+ }
0 commit comments