Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

fixed-width-int

A robust implementation of fixed-width integers in Python that precisely emulates C-style behavior. Ideal for low-level programming, hardware emulation, and situations requiring exact control over integer representation and arithmetic.

Features

  • C-like Behavior:
    • Two's complement signed integers
    • Modular arithmetic for unsigned integers
    • Value wrapping on overflow/underflow
    • C-style division (truncates toward zero)
    • C-style modulo (matches division behavior)
    • Automatic type promotion
  • Type System:
    • Dynamic type creation via bit-width parameterization (e.g., Unsigned[8], Signed[10])
    • Intuitive subtype relationships:
      • Signed[m] is a supertype of Signed[n] when m > n
      • Unsigned[m] is a supertype of Unsigned[n] when m > n
      • Signed[m] is a supertype of Unsigned[n] when m > n
    • Full support for isinstance and issubclass checks
  • Compatibility
    • Pure Python
    • Supports Python 2+

Installation

pip install fixed-width-int

Quick Start

from fixed_width_int import Unsigned, Signed

# Type definitions
U8 = Unsigned[8]   # 8-bit unsigned
S10 = Signed[10]   # 10-bit signed

# Basic operations
assert U8(255) + U8(1) == U8(0)        # Wraps around
assert S10(511) + S10(1) == S10(-512)  # Two's complement behavior

# Type promotion
assert type(U8(200) + S10(100)) is S10
assert U8(200) + S10(100) == S10(300)

Comprehensive Examples

Type System and Basic Operations

from fixed_width_int import Unsigned, Signed

# Type definitions
U8 = Unsigned[8]
U16 = Unsigned[16]
S8 = Signed[8]
S16 = Signed[16]

# Subtyping checks
assert issubclass(U8, U16)      # Wider unsigned types are supertypes
assert issubclass(S8, S16)      # Wider signed types are supertypes
assert issubclass(U8, S16)      # Unsigned is subtype of wider signed
assert not issubclass(S8, U16)  # Signed isn't subtype of wider unsigned

# Value wrapping
assert U8(256) == U8(0)        # Modular arithmetic
assert S8(128) == S8(-128)     # Two's complement wrap
assert S8(-129) == S8(127)     # Underflow handling

# Addition/subtraction
assert U8(200) + U8(100) == U8(44)   # 300 % 256
assert S8(-100) - S8(30) == S8(126) # Wraps around

# Multiplication
assert U8(20) * U8(13) == U8(4)      # 260 % 256
assert S8(-10) * S8(13) == S8(126)  # -130 wraps to 126

# C-style division
assert S8(7) / S8(3) == S8(2)       # Truncates toward zero
assert S8(-7) / S8(3) == S8(-2)     # Negative division

# C-style modulo
assert S8(7) % S8(3) == S8(1)
assert S8(-7) % S8(3) == S8(-1)       # Matches division

# Basic bitwise ops
assert U8(0b10101010) & U8(0b11001100) == U8(0b10001000)
assert U8(0b10101010) | U8(0b11001100) == U8(0b11101110)

# Shifts
assert S8(0b11110000) >> S8(2) == S8(-4)   # Arithmetic right shift
assert U8(0b11110000) >> U8(2) == U8(0b00111100)  # Logical right shift
assert U8(1) << U8(7) == U8(128)
assert U8(1) << U8(8) == U8(0)

# Exponentiation
assert pow(U8(3), U8(4)) == U8(81)
assert pow(S8(2), S8(5), S8(9)) == S8(5)  # With modulus

# Type coercion and promotion

# Coerced to unsigned
assert type(U8(200) + S8(100)) is U8
assert U8(200) + S8(100) == U8(44)

# Promoted to wider signed
assert type(S16(-10) + U8(10)) is S16
assert S16(-10) + U8(10) == S16(0)

# Coerced to wider unsigned
assert type(U16(10) + S8(-11)) is U16
assert U16(10) + S8(-11) == U16(65535)

# Comparisons
assert S8(-1) == U8(255)           # Value equality
assert U8(255) > S8(0)             # Comparison works across types
assert U8(1) < S8(-1)              # Because S8(-1) gets coerced to U8(255)

# Negation, identity, absolute
assert -S8(5) == S8(-5)
assert +S8(-5) == S8(-5)
assert abs(S8(-5)) == S8(5)
assert abs(S8(-128)) == S8(-128)  # Overflow!

Implementation Highlights

Core Architecture

  • Metaclass Magic: FixedWidthIntMeta dynamically creates fixed-width types while caching them for efficiency
  • Strict Type Safety: Prevents direct instantiation of raw Signed/Unsigned without bit-width specification

Key Components

  1. Metaclass FixedWidthIntMeta:

    • Dynamically generates concrete integer types through __getitem__
    • Manages type caching
    • Sets width-specific properties (BIT_WIDTH, MODULO, etc.)
  2. Base Class FixedWidthIntBase:

    • Implements all numbers.Integral abstract methods
    • Handles core arithmetic with proper wrapping behavior
    • Stores actual value in promoted_to_int
  • Signed and Unsigned Types:

    • Signed: Implements two's complement behavior
    • Unsigned: Implements modular arithmetic behavior
    • Both implement wrap_integral to handle value truncation/interpretation
    • Both implement __subclasshook__ to establish the subtype relationships described in the requirements
      • Carefully avoids infinite recursion
  • Preventing Direct Instantiation:

    • FixedWidthIntBase.__new__ checks if cls.BIT_WIDTH == inf
    • If true, raise an informative error telling users they must use Signed[bit_width] or Unsigned[bit_width] first
    • This prevents raw Signed() or Unsigned() instantiation
from fixed_width_int import Signed


# This works for type checking
assert issubclass(Signed[8], Signed)
assert issubclass(Signed[8], Signed[8])
assert issubclass(Signed[8], Signed[9])

assert isinstance(Signed[8](42), Signed)
assert isinstance(Signed[8](42), Signed[8])
assert isinstance(Signed[8](42), Signed[9])

# Raises ValueError about needing to specify bitwidth
Signed(42)

Why Use This Library?

  • Precision: Get exactly the integer behavior you need for emulators, protocols, or low-level code
  • Safety: Clear error messages and strict type checking prevent subtle bugs
  • Pythonic: Integrates smoothly with Python's type system and number hierarchy
  • Performance: Optimized implementation with minimal overhead

Contributing

Contributions are welcome! Please submit pull requests or open issues on the GitHub repository.

License

This project is licensed under the MIT License.

Release files for fixed-width-int 0.1.0a2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for fixed-width-int 0.1.0a2
File Size Uploaded
fixed_width_int-0.1.0a2.tar.gz 8.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for fixed-width-int 0.1.0a2
File Interpreter ABI Platform
fixed_width_int-0.1.0a2-py2.py3-none-any.whl Python 2, Python 3 none any Details

Total release size: 16.3 kB

Release files / fixed_width_int-0.1.0a2.tar.gz

Download URL fixed_width_int-0.1.0a2.tar.gz
Size 8.1 kB
Tags Source
SHA-256 checksum
How to use checksums
710b199761fe4574032bd1545712a71afb9831db236a62faf5ace528f1247d3d
BLAKE2b-256 checksum
How to use checksums
e1437b6c62d098d1dfc1f02e861b6a0aa70af778cfc6ca68405e265242ca849d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.2

Release files / fixed_width_int-0.1.0a2-py2.py3-none-any.whl

Download URL fixed_width_int-0.1.0a2-py2.py3-none-any.whl
Size 8.3 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
8f5881bfb21b7cd3e14f8d4c5cb1cf4f76f3818e04af755e7cdd819718b84c82
BLAKE2b-256 checksum
How to use checksums
24cfb98b6666ed5ddf9c3784e056de6e851fafdd85f0fa7c56d285c2d528f91e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.2

Release history Release notifications | RSS feed

This release

0.1.0a2 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page