Skip to content

fix(bigint): fix modpow normalization, right shift, and bit_length bugs#3338

Open
bobzhang wants to merge 2 commits intomainfrom
fix/bigint-modpow-shift-bitlen
Open

fix(bigint): fix modpow normalization, right shift, and bit_length bugs#3338
bobzhang wants to merge 2 commits intomainfrom
fix/bigint-modpow-shift-bitlen

Conversation

@bobzhang
Copy link
Copy Markdown
Contributor

@bobzhang bobzhang commented Mar 23, 2026

Summary

Three correctness fixes for the non-JS BigInt backend:

  1. Modular exponentiation (pow with modulus): Initialize result as 1%modulus (not 1) so modulus=1 returns 0. Normalize base into [0, modulus) before the loop so negative bases produce canonical non-negative results.

  2. Arithmetic right shift (>>): When shift amount is an exact multiple of 32 (r==0), the code was not checking if any dropped low limbs were non-zero. For negative numbers, floor division requires rounding toward negative infinity, so (-2^32-1)>>32 should be -2, not -1.

  3. bit_length for negative multi-limb powers of two: The power-of-two check started with limbs[0].popcnt()==1, which fails for numbers like -2^32 where limb 0 is 0 and limb 1 is 1. Fixed to count total set bits across all limbs.

Test plan

  • Added regression tests for all three bugs
  • moon test passes (151 bigint tests)

🤖 Generated with Claude Code


Open with Devin

@coveralls
Copy link
Copy Markdown
Collaborator

coveralls commented Mar 23, 2026

Pull Request Test Coverage Report for Build 3159

Details

  • 11 of 11 (100.0%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.001%) to 95.743%

Totals Coverage Status
Change from base Build 3157: 0.001%
Covered Lines: 13833
Relevant Lines: 14448

💛 - Coveralls

devin-ai-integration[bot]

This comment was marked as resolved.

@bobzhang bobzhang force-pushed the fix/bigint-modpow-shift-bitlen branch from 9db8408 to 618e830 Compare March 23, 2026 09:18
bobzhang and others added 2 commits March 25, 2026 08:12
Three correctness fixes for the non-JS BigInt backend:

1. Modular exponentiation (pow with modulus):
   - Initialize result as 1%modulus (not 1) so modulus=1 returns 0
   - Normalize base into [0, modulus) before the loop so negative
     bases produce canonical non-negative results

2. Arithmetic right shift (>>):
   - When shift amount is an exact multiple of 32 (r==0), the code
     was not checking if any dropped low limbs were non-zero.
     For negative numbers, floor division requires rounding toward
     negative infinity, so (-2^32-1)>>32 should be -2, not -1.

3. bit_length for negative multi-limb powers of two:
   - The power-of-two check started with limbs[0].popcnt()==1,
     which fails for numbers like -2^32 where limb 0 is 0 and
     limb 1 is 1. Fixed to count total set bits across all limbs.

Added regression tests for all three bugs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bobzhang bobzhang force-pushed the fix/bigint-modpow-shift-bitlen branch from 618e830 to 55189f3 Compare March 25, 2026 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants