fixedint
Advanced tools
| from typing import Optional, Type | ||
| import fixedint.base | ||
| from fixedint.aliases import * | ||
| # workaround for being unable to specify multiple inheritance in a type annotation | ||
| class _FixedInt(fixedint.base.FixedInt, int): ... # type: ignore[misc] | ||
| def FixedInt(width: int, signed: bool=True, mutable: Optional[bool] = None) -> Type[_FixedInt]: ... | ||
| def MutableFixedInt(width: int, signed: bool=True) -> Type[fixedint.base.MutableFixedInt]: ... |
| from fixedint.base import FixedInt, MutableFixedInt | ||
| # ignore mypy complaining about mismatching signatures | ||
| class Int8(FixedInt, int): ... # type: ignore[misc] | ||
| class Int16(FixedInt, int): ... # type: ignore[misc] | ||
| class Int32(FixedInt, int): ... # type: ignore[misc] | ||
| class Int64(FixedInt, int): ... # type: ignore[misc] | ||
| class UInt8(FixedInt, int): ... # type: ignore[misc] | ||
| class UInt16(FixedInt, int): ... # type: ignore[misc] | ||
| class UInt32(FixedInt, int): ... # type: ignore[misc] | ||
| class UInt64(FixedInt, int): ... # type: ignore[misc] | ||
| class MutableInt8(MutableFixedInt): ... | ||
| class MutableInt16(MutableFixedInt): ... | ||
| class MutableInt32(MutableFixedInt): ... | ||
| class MutableInt64(MutableFixedInt): ... | ||
| class MutableUInt8(MutableFixedInt): ... | ||
| class MutableUInt16(MutableFixedInt): ... | ||
| class MutableUInt32(MutableFixedInt): ... | ||
| class MutableUInt64(MutableFixedInt): ... |
| from typing import Optional, Type, TypeVar, Union | ||
| from numbers import Integral | ||
| FSelf = TypeVar("FSelf", bound="FixedInt") | ||
| Other = Union[Integral, "FixedInt"] | ||
| class FixedInt: | ||
| def __init__(self: FSelf, val: Union[int, str] = 0): ... | ||
| def __pow__(self: FSelf, other: Other, modulo: Optional[Other]=None) -> FSelf: ... | ||
| def __rpow__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __repr__(self: FSelf) -> str: ... | ||
| def __str__(self: FSelf) -> str: ... | ||
| def __getitem__(self: FSelf, item) -> FSelf: ... | ||
| @classmethod | ||
| def from_bytes(cls: Type[FSelf], bytes, byteorder: str='little', signed: Optional[bool]=None) -> FSelf: ... | ||
| def to_bytes(self: FSelf, length: Optional[int]=None, byteorder: str='little') -> bytes: ... | ||
| def __round__(self: FSelf, n: int=0) -> int: ... | ||
| def __neg__(self: FSelf) -> FSelf: ... | ||
| def __pos__(self: FSelf) -> FSelf: ... | ||
| def __abs__(self: FSelf) -> FSelf: ... | ||
| def __invert__(self: FSelf) -> FSelf: ... | ||
| def __add__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __sub__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __mul__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __floordiv__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __mod__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __lshift__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __rshift__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __and__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __xor__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __or__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __radd__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __rsub__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __rmul__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __rfloordiv__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __rmod__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __rand__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __rxor__(self: FSelf, other: Other) -> FSelf: ... | ||
| def __ror__(self: FSelf, other: Other) -> FSelf: ... | ||
| # Note that rlshift/rrshift are not overridden as we do not want the LHS | ||
| # to be forced to the same type if the fixed int is on the RHS | ||
| width: int | ||
| mutable: bool | ||
| signed: bool | ||
| maxval: int | ||
| minval: int | ||
| MSelf = TypeVar("MSelf", bound="MutableFixedInt") | ||
| class MutableFixedInt(FixedInt): | ||
| def __format__(self: MSelf, format_spec, /) -> str: ... | ||
| def __ipow__(self: MSelf, other: Other, modulo: Optional[Other]=None) -> MSelf: ... | ||
| def __setitem__(self: MSelf, item, value: Other) -> bool: ... | ||
| def __iadd__(self: MSelf, other: Other) -> MSelf: ... | ||
| def __isub__(self: MSelf, other: Other) -> MSelf: ... | ||
| def __imul__(self: MSelf, other: Other) -> MSelf: ... | ||
| def __ifloordiv__(self: MSelf, other: Other) -> MSelf: ... | ||
| def __imod__(self: MSelf, other: Other) -> MSelf: ... | ||
| def __ilshift__(self: MSelf, other: Other) -> MSelf: ... | ||
| def __irshift__(self: MSelf, other: Other) -> MSelf: ... | ||
| def __iand__(self: MSelf, other: Other) -> MSelf: ... | ||
| def __ior__(self: MSelf, other: Other) -> MSelf: ... | ||
| def __ixor__(self: MSelf, other: Other) -> MSelf: ... | ||
| def __int__(self: MSelf, /) -> int: ... | ||
| def __float__(self: MSelf, /) -> float: ... | ||
| def __index__(self: MSelf, /) -> int: ... | ||
| def __trunc__(self: MSelf) -> int: ... | ||
| def __bool__(self: MSelf) -> bool: ... | ||
| def __truediv__(self: MSelf, value: Other, /) -> float: ... | ||
| def __rtruediv__(self: MSelf, value: Other, /) -> float: ... | ||
| def __divmod__(self: MSelf, value: Other, /) -> tuple[int, int]: ... | ||
| def __rdivmod__(self: MSelf, value: Other, /) -> tuple[int, int]: ... | ||
| def __rlshift__(self: MSelf, value: Other, /) -> int: ... # type: ignore[misc] | ||
| def __rrshift__(self: MSelf, value: Other, /) -> int: ... # type: ignore[misc] | ||
| def __eq__(self: FSelf, value: object, /) -> bool: ... | ||
| def __ne__(self: FSelf, value: object, /) -> bool: ... | ||
| def __ge__(self: FSelf, value: Other, /) -> bool: ... | ||
| def __gt__(self: FSelf, value: Other, /) -> bool: ... | ||
| def __le__(self: FSelf, value: Other, /) -> bool: ... | ||
| def __lt__(self: FSelf, value: Other, /) -> bool: ... |
+5
-0
@@ -0,1 +1,6 @@ | ||
| v0.2.0, 2020-09-16: | ||
| Add type hints (GH #4) | ||
| Removed the broken MutableFixedInt.__itruediv__ | ||
| Added base argument to FixedInt constructor | ||
| v0.1.6, 2020-06-20: | ||
@@ -2,0 +7,0 @@ Fix x[:] = y where y is a fixedint (GH #3) |
+120
-115
@@ -1,4 +0,4 @@ | ||
| Metadata-Version: 1.1 | ||
| Metadata-Version: 2.1 | ||
| Name: fixedint | ||
| Version: 0.1.6 | ||
| Version: 0.2.0 | ||
| Summary: simple fixed-width integers | ||
@@ -9,115 +9,2 @@ Home-page: https://github.com/nneonneo/fixedint | ||
| License: PSF | ||
| Description: ===================================== | ||
| fixedint: simple fixed-width integers | ||
| ===================================== | ||
| This module provides fixed-size integer classes which retain their fixed nature across | ||
| arithmetic operations. It is geared towards users who need to emulate machine integers. | ||
| It provides flexible classes for defining integers with a fixed number of bits, as well | ||
| as predefined classes for common machine integer sizes. These classes can be used as | ||
| drop-in replacements for int/long, and can be sliced to extract bitfields. | ||
| Mutable versions of these integers are provided, enabling usages such as emulation of | ||
| machine registers. | ||
| Basic Usage | ||
| =========== | ||
| A collection of predefined fixed-width integers for widths 8, 16, 32 and 64 are available | ||
| in signed and unsigned varieties. Mutable and immutable versions of each type are provided. | ||
| These are named as ``[Mutable][U]Int<N>``, e.g. ``UInt64`` or ``MutableInt8``. Use these | ||
| classes as you would ``int``; arithmetic operations involving these classes will preserve | ||
| fixed width. For example:: | ||
| x = UInt32(0) | ||
| print(hex(~x)) # prints 0xffffffff | ||
| Mutable instances can be modified in-place, preserving their type:: | ||
| x = MutableUInt32(0) | ||
| y = x | ||
| x += 100 | ||
| print(y) # prints 100 | ||
| To set a mutable integer without losing its type, use slicing:: | ||
| x = MutableUInt32(0) | ||
| x[:] = -1 | ||
| print(hex(x)) # prints 0xffffffff | ||
| Arithmetic Operations | ||
| ===================== | ||
| ``FixedInt`` instances support all arithmetic operators. For binary operators, both | ||
| operands are converted to plain Python ``int`` and then operated on. With a few | ||
| exceptions, the result will be cast back to a ``FixedInt`` large enough to hold either | ||
| operand, provided one of the operands was a ``FixedInt``. Note that the resulting | ||
| ``FixedInt`` may not be large enough to hold the complete result, in which case the | ||
| result will be truncated. | ||
| The exceptions are as follows: | ||
| * ``divmod`` returns a tuple of plain ``int`` s | ||
| * true division returns a float | ||
| * ``**``, ``<<`` and ``>>`` will return a ``FixedInt`` if the left operand was a | ||
| ``FixedInt``, and plain ``int`` otherwise. | ||
| Mutable instances additionally support in-place operations, which will modify the | ||
| value without altering its type. | ||
| Arithmetic operations between two integers of different sizes follow C integer promotion | ||
| rules when determining the type of the final result. These rules boil down to the | ||
| following: | ||
| * If the operands are both signed, or both unsigned, the wider of the two operand types is chosen. | ||
| * Otherwise, if the unsigned operand is wider, the unsigned operand is chosen. | ||
| * Otherwise, the signed operand is chosen. | ||
| Slicing | ||
| ======= | ||
| ``FixedInt`` instances support slicing. Slicing with a single integer produces a single | ||
| Boolean value representing the bit at that position. Slicing with a range produces a | ||
| ``FixedInt`` containing the range of bits. Mutable instances additionally support slice | ||
| assignment. This makes e.g. manipulating a flag register straightforward, without needing | ||
| to use bitwise operations. | ||
| All indexing operations treat the least-significant bit (LSB) as bit 0. Currently, only | ||
| contiguous bit sections can be obtained; for more flexibility consider using a module | ||
| such as `bitarray`. | ||
| Getting a slice results in a ``FixedInt`` instance with exactly as many bits as the range. | ||
| This can be used to perform wraparound arithmetic on a bit field. | ||
| Slices support two main syntaxes:: | ||
| value[<start>:<end>] | ||
| value[<start>:<length>j] | ||
| The latter syntax is more convenient when dealing with fixed-width fields. Both of the | ||
| slice arguments may be omitted, in which case they will default to the LSB and MSB of | ||
| the ``FixedInt`` respectively. | ||
| Byte Conversion | ||
| =============== | ||
| ``FixedInt`` instances can be converted to and from raw byte representations by using the | ||
| ``.to_bytes`` instance method and the ``.from_bytes`` classmethod. The usage of these | ||
| methods matches that of Python 3.4's ``int.to_bytes`` and ``int.from_bytes`` methods. | ||
| Platform: UNKNOWN | ||
| Classifier: License :: OSI Approved :: Python Software Foundation License | ||
@@ -134,2 +21,120 @@ Classifier: Development Status :: 4 - Beta | ||
| Classifier: Programming Language :: Python :: 3.8 | ||
| Classifier: Programming Language :: Python :: 3.9 | ||
| Classifier: Programming Language :: Python :: 3.10 | ||
| Classifier: Programming Language :: Python :: 3.11 | ||
| Classifier: Topic :: Utilities | ||
| License-File: LICENSE | ||
| License-File: AUTHORS | ||
| ===================================== | ||
| fixedint: simple fixed-width integers | ||
| ===================================== | ||
| This module provides fixed-size integer classes which retain their fixed nature across | ||
| arithmetic operations. It is geared towards users who need to emulate machine integers. | ||
| It provides flexible classes for defining integers with a fixed number of bits, as well | ||
| as predefined classes for common machine integer sizes. These classes can be used as | ||
| drop-in replacements for int/long, and can be sliced to extract bitfields. | ||
| Mutable versions of these integers are provided, enabling usages such as emulation of | ||
| machine registers. | ||
| Basic Usage | ||
| =========== | ||
| A collection of predefined fixed-width integers for widths 8, 16, 32 and 64 are available | ||
| in signed and unsigned varieties. Mutable and immutable versions of each type are provided. | ||
| These are named as ``[Mutable][U]Int<N>``, e.g. ``UInt64`` or ``MutableInt8``. Use these | ||
| classes as you would ``int``; arithmetic operations involving these classes will preserve | ||
| fixed width. For example:: | ||
| x = UInt32(0) | ||
| print(hex(~x)) # prints 0xffffffff | ||
| Mutable instances can be modified in-place, preserving their type:: | ||
| x = MutableUInt32(0) | ||
| y = x | ||
| x += 100 | ||
| print(y) # prints 100 | ||
| To set a mutable integer without losing its type, use slicing:: | ||
| x = MutableUInt32(0) | ||
| x[:] = -1 | ||
| print(hex(x)) # prints 0xffffffff | ||
| Arithmetic Operations | ||
| ===================== | ||
| ``FixedInt`` instances support all arithmetic operators. For binary operators, both | ||
| operands are converted to plain Python ``int`` and then operated on. With a few | ||
| exceptions, the result will be cast back to a ``FixedInt`` large enough to hold either | ||
| operand, provided one of the operands was a ``FixedInt``. Note that the resulting | ||
| ``FixedInt`` may not be large enough to hold the complete result, in which case the | ||
| result will be truncated. | ||
| The exceptions are as follows: | ||
| * ``divmod`` returns a tuple of plain ``int`` s | ||
| * true division returns a float | ||
| * ``**``, ``<<`` and ``>>`` will return a ``FixedInt`` if the left operand was a | ||
| ``FixedInt``, and plain ``int`` otherwise. | ||
| Mutable instances additionally support in-place operations, which will modify the | ||
| value without altering its type. | ||
| Arithmetic operations between two integers of different sizes follow C integer promotion | ||
| rules when determining the type of the final result. These rules boil down to the | ||
| following: | ||
| * If the operands are both signed, or both unsigned, the wider of the two operand types is chosen. | ||
| * Otherwise, if the unsigned operand is wider, the unsigned operand is chosen. | ||
| * Otherwise, the signed operand is chosen. | ||
| Slicing | ||
| ======= | ||
| ``FixedInt`` instances support slicing. Slicing with a single integer produces a single | ||
| Boolean value representing the bit at that position. Slicing with a range produces a | ||
| ``FixedInt`` containing the range of bits. Mutable instances additionally support slice | ||
| assignment. This makes e.g. manipulating a flag register straightforward, without needing | ||
| to use bitwise operations. | ||
| All indexing operations treat the least-significant bit (LSB) as bit 0. Currently, only | ||
| contiguous bit sections can be obtained; for more flexibility consider using a module | ||
| such as `bitarray`. | ||
| Getting a slice results in a ``FixedInt`` instance with exactly as many bits as the range. | ||
| This can be used to perform wraparound arithmetic on a bit field. | ||
| Slices support two main syntaxes:: | ||
| value[<start>:<end>] | ||
| value[<start>:<length>j] | ||
| The latter syntax is more convenient when dealing with fixed-width fields. Either of the | ||
| slice arguments may be omitted, in which case they will default to the LSB and MSB of | ||
| the ``FixedInt`` respectively. | ||
| Byte Conversion | ||
| =============== | ||
| ``FixedInt`` instances can be converted to and from raw byte representations by using the | ||
| ``.to_bytes`` instance method and the ``.from_bytes`` classmethod. The usage of these | ||
| methods matches that of Python 3.4's ``int.to_bytes`` and ``int.from_bytes`` methods, but | ||
| the length is automatically inferred from the integer width. | ||
@@ -8,5 +8,9 @@ AUTHORS | ||
| fixedint/__init__.py | ||
| fixedint/__init__.pyi | ||
| fixedint/aliases.py | ||
| fixedint/aliases.pyi | ||
| fixedint/base.py | ||
| fixedint/base.pyi | ||
| fixedint/compat.py | ||
| fixedint/py.typed | ||
| fixedint/test_fixedint.py | ||
@@ -13,0 +17,0 @@ fixedint/util.py |
@@ -1,2 +0,2 @@ | ||
| from fixedint.base import FixedInt, MutableFixedInt | ||
| from fixedint import FixedInt, MutableFixedInt | ||
@@ -3,0 +3,0 @@ __all__ = [] |
+7
-3
@@ -100,5 +100,9 @@ # -*- coding: utf-8 -*- | ||
| intbase = bases[1] | ||
| def _newfunc(cls, val=0): | ||
| def _newfunc(cls, val=0, base=None): | ||
| ''' Convert an integer into a fixed-width integer. ''' | ||
| return intbase.__new__(cls, _rectify(int(val))) | ||
| if base is None: | ||
| val = int(val) | ||
| else: | ||
| val = int(val, base) | ||
| return intbase.__new__(cls, _rectify(val)) | ||
| _newfunc.__name__ = '__new__' | ||
@@ -462,3 +466,3 @@ dict['__new__'] = _newfunc | ||
| # pow is special because it takes three arguments. | ||
| _inplace_func = 'add,+ sub,- mul,* truediv,/ floordiv,// mod,% lshift,<< rshift,<< and,& or,| xor,^'.split() | ||
| _inplace_func = 'add,+ sub,- mul,* floordiv,// mod,% lshift,<< rshift,<< and,& or,| xor,^'.split() | ||
| if not PY3K: | ||
@@ -465,0 +469,0 @@ _inplace_func += ['div,/'] |
@@ -8,3 +8,3 @@ import unittest | ||
| tests = [] | ||
| tests = [] # type: list[type[unittest.TestCase]] | ||
@@ -33,3 +33,3 @@ # ---------------------------------------------------------------------------- | ||
| from fixedint.util import HexFormattingMixin | ||
| class MyUInt32(HexFormattingMixin, UInt32): | ||
| class MyUInt32(HexFormattingMixin, UInt32): # type: ignore[misc] | ||
| pass | ||
@@ -36,0 +36,0 @@ self.assertEqual(str(MyUInt32(32)), '0x00000020') |
+120
-115
@@ -1,4 +0,4 @@ | ||
| Metadata-Version: 1.1 | ||
| Metadata-Version: 2.1 | ||
| Name: fixedint | ||
| Version: 0.1.6 | ||
| Version: 0.2.0 | ||
| Summary: simple fixed-width integers | ||
@@ -9,115 +9,2 @@ Home-page: https://github.com/nneonneo/fixedint | ||
| License: PSF | ||
| Description: ===================================== | ||
| fixedint: simple fixed-width integers | ||
| ===================================== | ||
| This module provides fixed-size integer classes which retain their fixed nature across | ||
| arithmetic operations. It is geared towards users who need to emulate machine integers. | ||
| It provides flexible classes for defining integers with a fixed number of bits, as well | ||
| as predefined classes for common machine integer sizes. These classes can be used as | ||
| drop-in replacements for int/long, and can be sliced to extract bitfields. | ||
| Mutable versions of these integers are provided, enabling usages such as emulation of | ||
| machine registers. | ||
| Basic Usage | ||
| =========== | ||
| A collection of predefined fixed-width integers for widths 8, 16, 32 and 64 are available | ||
| in signed and unsigned varieties. Mutable and immutable versions of each type are provided. | ||
| These are named as ``[Mutable][U]Int<N>``, e.g. ``UInt64`` or ``MutableInt8``. Use these | ||
| classes as you would ``int``; arithmetic operations involving these classes will preserve | ||
| fixed width. For example:: | ||
| x = UInt32(0) | ||
| print(hex(~x)) # prints 0xffffffff | ||
| Mutable instances can be modified in-place, preserving their type:: | ||
| x = MutableUInt32(0) | ||
| y = x | ||
| x += 100 | ||
| print(y) # prints 100 | ||
| To set a mutable integer without losing its type, use slicing:: | ||
| x = MutableUInt32(0) | ||
| x[:] = -1 | ||
| print(hex(x)) # prints 0xffffffff | ||
| Arithmetic Operations | ||
| ===================== | ||
| ``FixedInt`` instances support all arithmetic operators. For binary operators, both | ||
| operands are converted to plain Python ``int`` and then operated on. With a few | ||
| exceptions, the result will be cast back to a ``FixedInt`` large enough to hold either | ||
| operand, provided one of the operands was a ``FixedInt``. Note that the resulting | ||
| ``FixedInt`` may not be large enough to hold the complete result, in which case the | ||
| result will be truncated. | ||
| The exceptions are as follows: | ||
| * ``divmod`` returns a tuple of plain ``int`` s | ||
| * true division returns a float | ||
| * ``**``, ``<<`` and ``>>`` will return a ``FixedInt`` if the left operand was a | ||
| ``FixedInt``, and plain ``int`` otherwise. | ||
| Mutable instances additionally support in-place operations, which will modify the | ||
| value without altering its type. | ||
| Arithmetic operations between two integers of different sizes follow C integer promotion | ||
| rules when determining the type of the final result. These rules boil down to the | ||
| following: | ||
| * If the operands are both signed, or both unsigned, the wider of the two operand types is chosen. | ||
| * Otherwise, if the unsigned operand is wider, the unsigned operand is chosen. | ||
| * Otherwise, the signed operand is chosen. | ||
| Slicing | ||
| ======= | ||
| ``FixedInt`` instances support slicing. Slicing with a single integer produces a single | ||
| Boolean value representing the bit at that position. Slicing with a range produces a | ||
| ``FixedInt`` containing the range of bits. Mutable instances additionally support slice | ||
| assignment. This makes e.g. manipulating a flag register straightforward, without needing | ||
| to use bitwise operations. | ||
| All indexing operations treat the least-significant bit (LSB) as bit 0. Currently, only | ||
| contiguous bit sections can be obtained; for more flexibility consider using a module | ||
| such as `bitarray`. | ||
| Getting a slice results in a ``FixedInt`` instance with exactly as many bits as the range. | ||
| This can be used to perform wraparound arithmetic on a bit field. | ||
| Slices support two main syntaxes:: | ||
| value[<start>:<end>] | ||
| value[<start>:<length>j] | ||
| The latter syntax is more convenient when dealing with fixed-width fields. Both of the | ||
| slice arguments may be omitted, in which case they will default to the LSB and MSB of | ||
| the ``FixedInt`` respectively. | ||
| Byte Conversion | ||
| =============== | ||
| ``FixedInt`` instances can be converted to and from raw byte representations by using the | ||
| ``.to_bytes`` instance method and the ``.from_bytes`` classmethod. The usage of these | ||
| methods matches that of Python 3.4's ``int.to_bytes`` and ``int.from_bytes`` methods. | ||
| Platform: UNKNOWN | ||
| Classifier: License :: OSI Approved :: Python Software Foundation License | ||
@@ -134,2 +21,120 @@ Classifier: Development Status :: 4 - Beta | ||
| Classifier: Programming Language :: Python :: 3.8 | ||
| Classifier: Programming Language :: Python :: 3.9 | ||
| Classifier: Programming Language :: Python :: 3.10 | ||
| Classifier: Programming Language :: Python :: 3.11 | ||
| Classifier: Topic :: Utilities | ||
| License-File: LICENSE | ||
| License-File: AUTHORS | ||
| ===================================== | ||
| fixedint: simple fixed-width integers | ||
| ===================================== | ||
| This module provides fixed-size integer classes which retain their fixed nature across | ||
| arithmetic operations. It is geared towards users who need to emulate machine integers. | ||
| It provides flexible classes for defining integers with a fixed number of bits, as well | ||
| as predefined classes for common machine integer sizes. These classes can be used as | ||
| drop-in replacements for int/long, and can be sliced to extract bitfields. | ||
| Mutable versions of these integers are provided, enabling usages such as emulation of | ||
| machine registers. | ||
| Basic Usage | ||
| =========== | ||
| A collection of predefined fixed-width integers for widths 8, 16, 32 and 64 are available | ||
| in signed and unsigned varieties. Mutable and immutable versions of each type are provided. | ||
| These are named as ``[Mutable][U]Int<N>``, e.g. ``UInt64`` or ``MutableInt8``. Use these | ||
| classes as you would ``int``; arithmetic operations involving these classes will preserve | ||
| fixed width. For example:: | ||
| x = UInt32(0) | ||
| print(hex(~x)) # prints 0xffffffff | ||
| Mutable instances can be modified in-place, preserving their type:: | ||
| x = MutableUInt32(0) | ||
| y = x | ||
| x += 100 | ||
| print(y) # prints 100 | ||
| To set a mutable integer without losing its type, use slicing:: | ||
| x = MutableUInt32(0) | ||
| x[:] = -1 | ||
| print(hex(x)) # prints 0xffffffff | ||
| Arithmetic Operations | ||
| ===================== | ||
| ``FixedInt`` instances support all arithmetic operators. For binary operators, both | ||
| operands are converted to plain Python ``int`` and then operated on. With a few | ||
| exceptions, the result will be cast back to a ``FixedInt`` large enough to hold either | ||
| operand, provided one of the operands was a ``FixedInt``. Note that the resulting | ||
| ``FixedInt`` may not be large enough to hold the complete result, in which case the | ||
| result will be truncated. | ||
| The exceptions are as follows: | ||
| * ``divmod`` returns a tuple of plain ``int`` s | ||
| * true division returns a float | ||
| * ``**``, ``<<`` and ``>>`` will return a ``FixedInt`` if the left operand was a | ||
| ``FixedInt``, and plain ``int`` otherwise. | ||
| Mutable instances additionally support in-place operations, which will modify the | ||
| value without altering its type. | ||
| Arithmetic operations between two integers of different sizes follow C integer promotion | ||
| rules when determining the type of the final result. These rules boil down to the | ||
| following: | ||
| * If the operands are both signed, or both unsigned, the wider of the two operand types is chosen. | ||
| * Otherwise, if the unsigned operand is wider, the unsigned operand is chosen. | ||
| * Otherwise, the signed operand is chosen. | ||
| Slicing | ||
| ======= | ||
| ``FixedInt`` instances support slicing. Slicing with a single integer produces a single | ||
| Boolean value representing the bit at that position. Slicing with a range produces a | ||
| ``FixedInt`` containing the range of bits. Mutable instances additionally support slice | ||
| assignment. This makes e.g. manipulating a flag register straightforward, without needing | ||
| to use bitwise operations. | ||
| All indexing operations treat the least-significant bit (LSB) as bit 0. Currently, only | ||
| contiguous bit sections can be obtained; for more flexibility consider using a module | ||
| such as `bitarray`. | ||
| Getting a slice results in a ``FixedInt`` instance with exactly as many bits as the range. | ||
| This can be used to perform wraparound arithmetic on a bit field. | ||
| Slices support two main syntaxes:: | ||
| value[<start>:<end>] | ||
| value[<start>:<length>j] | ||
| The latter syntax is more convenient when dealing with fixed-width fields. Either of the | ||
| slice arguments may be omitted, in which case they will default to the LSB and MSB of | ||
| the ``FixedInt`` respectively. | ||
| Byte Conversion | ||
| =============== | ||
| ``FixedInt`` instances can be converted to and from raw byte representations by using the | ||
| ``.to_bytes`` instance method and the ``.from_bytes`` classmethod. The usage of these | ||
| methods matches that of Python 3.4's ``int.to_bytes`` and ``int.from_bytes`` methods, but | ||
| the length is automatically inferred from the integer width. | ||
+3
-2
@@ -97,3 +97,3 @@ ===================================== | ||
| The latter syntax is more convenient when dealing with fixed-width fields. Both of the | ||
| The latter syntax is more convenient when dealing with fixed-width fields. Either of the | ||
| slice arguments may be omitted, in which case they will default to the LSB and MSB of | ||
@@ -109,3 +109,4 @@ the ``FixedInt`` respectively. | ||
| ``.to_bytes`` instance method and the ``.from_bytes`` classmethod. The usage of these | ||
| methods matches that of Python 3.4's ``int.to_bytes`` and ``int.from_bytes`` methods. | ||
| methods matches that of Python 3.4's ``int.to_bytes`` and ``int.from_bytes`` methods, but | ||
| the length is automatically inferred from the integer width. | ||
@@ -112,0 +113,0 @@ |
+5
-1
@@ -17,3 +17,3 @@ try: | ||
| name = 'fixedint', | ||
| version = '0.1.6', | ||
| version = '0.2.0', | ||
| author = 'Robert Xiao', | ||
@@ -35,2 +35,5 @@ author_email = 'robert.bo.xiao@gmail.com', | ||
| "Programming Language :: Python :: 3.8", | ||
| "Programming Language :: Python :: 3.9", | ||
| "Programming Language :: Python :: 3.10", | ||
| "Programming Language :: Python :: 3.11", | ||
| "Topic :: Utilities", | ||
@@ -40,3 +43,4 @@ ], | ||
| packages = ['fixedint'], | ||
| package_data = {"fixedint": ["py.typed", "*.pyi"]}, | ||
| long_description=long_description, | ||
| ) |
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
52683
10.11%22
22.22%857
14.57%