1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
Metadata-Version: 2.1
Name: fixedint
Version: 0.1.6
Summary: simple fixed-width integers
Home-page: https://github.com/nneonneo/fixedint
Author: Robert Xiao
Author-email: robert.bo.xiao@gmail.com
License: PSF
Platform: UNKNOWN
Classifier: License :: OSI Approved :: Python Software Foundation License
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Topic :: Utilities
=====================================
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.
|