Skip to content

Conversation

@AliAlimohammadi
Copy link
Contributor

@AliAlimohammadi AliAlimohammadi commented Jan 7, 2026

Description

This PR adds implementations of four types of binary shift operations to the bit_manipulation module, with binary string output for visualization and educational purposes.

Implementation Details

The implementation provides four main functions:

  1. logical_left_shift(number: i32, shift_amount: i32) -> Result<String, String>

    • Shifts bits to the left, filling with zeros on the right
    • Equivalent to multiplication by 2^shift_amount
    • Returns binary string representation with "0b" prefix
    • Both inputs must be non-negative
    • Format matches Python's approach: appends zeros to binary string
  2. logical_right_shift(number: i32, shift_amount: i32) -> Result<String, String>

    • Shifts bits to the right, filling with zeros on the left (unsigned shift)
    • Equivalent to division by 2^shift_amount (truncated)
    • Returns binary string representation with "0b" prefix
    • Both inputs must be non-negative
    • Format: minimal binary representation (not padded to 32 bits)
  3. arithmetic_left_shift(number: i32, shift_amount: i32) -> Result<String, String>

    • Shifts bits to the left, filling with zeros on the right
    • Note: Identical to logical left shift (included for completeness)
    • The distinction between arithmetic and logical only matters for right shifts
    • Returns binary string representation with "0b" prefix
    • shift_amount must be non-negative
    • Can accept negative numbers (will be interpreted as unsigned for the shift)
  4. arithmetic_right_shift(number: i32, shift_amount: i32) -> Result<String, String>

    • Shifts bits to the right, preserving the sign bit
    • For positive numbers: fills with 0s
    • For negative numbers: fills with 1s (sign extension)
    • Returns binary string representation with "0b" prefix and sign bit
    • Uses two's complement representation for negative numbers
    • Number can be negative, shift_amount must be non-negative
    • Format matches Python's approach exactly

Algorithm Details

Logical Left Shift:

Binary string manipulation: bin(number) + "0" * shift_amount
Example: 17 (0b10001) << 2 = "10001" + "00" = 0b1000100
  • Time complexity: $O(1)$ for computation, $O(n)$ for string formatting where n is bit length
  • Space complexity: $O(n)$ for output string

Logical Right Shift:

Standard unsigned right shift: (number as unsigned) >> shift_amount
Example: 17 (0b10001) >> 2 = 4 (0b100)
  • Time complexity: $O(1)$
  • Space complexity: $O(n)$ for output string

Arithmetic Left Shift:

Same as logical left shift: number << shift_amount
Example: 17 (0b10001) << 2 = 68 (0b1000100)
  • Time complexity: $O(1)$
  • Space complexity: $O(n)$ for output string

Arithmetic Right Shift:

Sign-preserving right shift with two's complement for negatives
Example (positive): 17 (0b010001) >> 2 = 4 (0b000100)
Example (negative): -17 (0b111011) >> 2 = -5 (0b11111011)
  • Time complexity: $O(n)$ where n is bit length (for two's complement calculation)
  • Space complexity: $O(n)$ for output string

Key Features

  1. Type Safety: Uses Result for error handling
  2. Validation: Checks for negative inputs where appropriate
  3. Educational: Returns binary string representation for visualization
  4. Standard Format: Uses "0b" prefix consistent with Rust/Python conventions
  5. Completeness: Includes all four shift types for comprehensive coverage
  6. Sign Handling: Arithmetic right shift properly handles negative numbers using two's complement
  7. Python-Compatible: Output format matches Python implementation exactly
  8. Comprehensive Tests: 35+ test cases covering all edge cases

Shift Types Explained

Logical Left Shift (<<)

  • Moves all bits to the left
  • Fills empty right positions with 0s
  • Can overflow (bits shifted out are lost)
  • Example: 0b0101 << 2 = 0b010100

Arithmetic Left Shift (<<)

  • Identical to logical left shift
  • Included for educational completeness
  • The "arithmetic" vs "logical" distinction only applies to right shifts

Logical Right Shift (>>> in some languages)

  • Moves all bits to the right
  • Fills empty left positions with 0s (unsigned)
  • Bits shifted out are lost
  • Example: 0b1010 >> 2 = 0b0010

Arithmetic Right Shift (>>)

  • Moves all bits to the right
  • Fills empty left positions with sign bit (0 for positive, 1 for negative)
  • Preserves sign of the number
  • Uses two's complement representation for negative numbers
  • Example (positive): 0b010001 >> 2 = 0b000100
  • Example (negative): 0b111011 >> 2 = 0b11111011

Two's Complement Implementation

For negative numbers in arithmetic right shift, the implementation follows Python's approach:

  1. Calculate binary length from absolute value
  2. Compute two's complement: abs(number) - (1 << binary_length)
  3. Prepend '1' as sign bit
  4. Apply shift with sign extension

This ensures correct representation of negative numbers in binary form.

Changes Made

  • ✅ Added src/bit_manipulation/binary_shifts.rs with complete implementation
  • ✅ Updated src/bit_manipulation/mod.rs to include and export the module
  • ✅ Implemented comprehensive unit tests (35+ tests) covering:
    • Logical left shift with various inputs (zero, one, large shifts, large numbers)
    • Logical right shift with various inputs (zero, one, shift all bits, large numbers)
    • Arithmetic left shift (basic operations, negative numbers, equivalence to logical left)
    • Arithmetic right shift for positive numbers (basic, large shifts, sign preservation)
    • Arithmetic right shift for negative numbers (basic, sign extension, two's complement)
    • Error handling (negative inputs for logical shifts, negative shift amounts)
    • Edge cases (large shift amounts, zero values)
    • Comparison of all four shift types on same value
    • Sign bit preservation verification
  • ✅ Added detailed documentation with examples for all public functions
  • ✅ Included doctests demonstrating usage
  • ✅ Module documentation explaining all shift types

Type of Change

  • New bit manipulation implementation
  • Documentation (docstrings and examples)
  • Tests (35+ comprehensive tests)

Test Coverage

35+ Unit Tests Including:

  • Logical left shift: zero, one, large shifts, large numbers, negative input validation
  • Logical right shift: zero, one, shift all bits, large numbers, negative input validation
  • Arithmetic left shift: basic operations, negative numbers, equivalence to logical left, zero input
  • Arithmetic right shift:
    • Positive numbers (zero, one, basic cases)
    • Negative numbers (-1, -17, sign preservation)
    • Large shift amounts (positive and negative numbers)
    • Sign bit preservation
  • Comparison of all shift types on same value
  • Doctests for public API

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my implementation is correct
  • New and existing unit tests pass locally with my changes
  • I have checked my code with cargo fmt
  • I have checked my code with cargo clippy
  • Module is properly exported in mod.rs

Additional Context

  • Type Safety: Uses Result type for error handling instead of exceptions
  • Clear Semantics: Separate functions for each shift type
  • Validation: Input validation with descriptive error messages
  • Idiomatic Rust: Uses Rust conventions and idioms
  • Documentation: Comprehensive rustdoc with examples and explanations
  • Educational: Clear explanations of each shift type with visual examples

References

@AliAlimohammadi
Copy link
Contributor Author

@siriak, this is ready to be merged.

@codecov-commenter
Copy link

Codecov Report

❌ Patch coverage is 99.43182% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 95.86%. Comparing base (6937f91) to head (3e9a2ca).

Files with missing lines Patch % Lines
src/bit_manipulation/binary_shifts.rs 99.43% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #988      +/-   ##
==========================================
+ Coverage   95.80%   95.86%   +0.05%     
==========================================
  Files         357      358       +1     
  Lines       23965    24141     +176     
==========================================
+ Hits        22960    23142     +182     
+ Misses       1005      999       -6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@siriak siriak merged commit a82ee7d into TheAlgorithms:master Jan 7, 2026
7 checks passed
@AliAlimohammadi AliAlimohammadi deleted the add-binary-shifts branch January 7, 2026 18:02
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.

3 participants