flexfloat 0.1.3__py3-none-any.whl → 0.1.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- flexfloat/__init__.py +21 -17
- flexfloat/bitarray/__init__.py +21 -80
- flexfloat/bitarray/bitarray.py +154 -54
- flexfloat/bitarray/bitarray_bigint.py +305 -0
- flexfloat/bitarray/bitarray_bool.py +202 -0
- flexfloat/bitarray/bitarray_int64.py +174 -149
- flexfloat/bitarray/bitarray_mixins.py +110 -47
- flexfloat/core.py +215 -113
- flexfloat/types.py +7 -1
- {flexfloat-0.1.3.dist-info → flexfloat-0.1.5.dist-info}/METADATA +1 -1
- flexfloat-0.1.5.dist-info/RECORD +15 -0
- flexfloat/bitarray/bitarray_list.py +0 -187
- flexfloat-0.1.3.dist-info/RECORD +0 -14
- {flexfloat-0.1.3.dist-info → flexfloat-0.1.5.dist-info}/WHEEL +0 -0
- {flexfloat-0.1.3.dist-info → flexfloat-0.1.5.dist-info}/licenses/LICENSE +0 -0
- {flexfloat-0.1.3.dist-info → flexfloat-0.1.5.dist-info}/top_level.txt +0 -0
flexfloat/__init__.py
CHANGED
@@ -1,32 +1,36 @@
|
|
1
1
|
"""FlexFloat - A library for arbitrary precision floating point arithmetic.
|
2
2
|
|
3
|
-
This package provides the FlexFloat class for handling floating-point numbers
|
4
|
-
|
3
|
+
This package provides the FlexFloat class for handling floating-point numbers with
|
4
|
+
growable exponents and fixed-size fractions. It also provides several BitArray
|
5
|
+
implementations for efficient bit manipulation.
|
6
|
+
|
7
|
+
Example:
|
8
|
+
from flexfloat import FlexFloat
|
9
|
+
x = FlexFloat(1.5, exponent_length=8, fraction_length=23)
|
10
|
+
print(x)
|
11
|
+
# Output: FlexFloat(sign=False, exponent=..., fraction=...)
|
12
|
+
|
13
|
+
Modules:
|
14
|
+
core: Main FlexFloat class implementation
|
15
|
+
bitarray: BitArray implementations (bool, int64, bigint)
|
16
|
+
types: Type definitions
|
5
17
|
"""
|
6
18
|
|
7
19
|
from .bitarray import (
|
20
|
+
BigIntBitArray,
|
8
21
|
BitArray,
|
9
|
-
|
10
|
-
|
11
|
-
ListBitArray,
|
12
|
-
create_bitarray,
|
13
|
-
get_available_implementations,
|
14
|
-
parse_bitarray,
|
15
|
-
set_default_implementation,
|
22
|
+
ListBoolBitArray,
|
23
|
+
ListInt64BitArray,
|
16
24
|
)
|
17
25
|
from .core import FlexFloat
|
18
26
|
|
19
|
-
__version__ = "0.1.
|
27
|
+
__version__ = "0.1.5"
|
20
28
|
__author__ = "Ferran Sanchez Llado"
|
21
29
|
|
22
30
|
__all__ = [
|
23
31
|
"FlexFloat",
|
24
|
-
"BitArrayType",
|
25
32
|
"BitArray",
|
26
|
-
"
|
27
|
-
"
|
28
|
-
"
|
29
|
-
"set_default_implementation",
|
30
|
-
"get_available_implementations",
|
31
|
-
"parse_bitarray",
|
33
|
+
"ListBoolBitArray",
|
34
|
+
"ListInt64BitArray",
|
35
|
+
"BigIntBitArray",
|
32
36
|
]
|
flexfloat/bitarray/__init__.py
CHANGED
@@ -1,90 +1,31 @@
|
|
1
|
-
"""BitArray implementation for the flexfloat package.
|
1
|
+
"""BitArray implementation for the flexfloat package.
|
2
|
+
|
3
|
+
This module provides a factory and utilities for working with different BitArray
|
4
|
+
implementations, including:
|
5
|
+
- ListBoolBitArray: List of booleans (default, flexible, easy to use)
|
6
|
+
- ListInt64BitArray: List of int64 chunks (memory efficient for large arrays)
|
7
|
+
- BigIntBitArray: Single Python int (arbitrary size, efficient for very large
|
8
|
+
arrays)
|
9
|
+
|
10
|
+
Example:
|
11
|
+
from flexfloat.bitarray import create_bitarray
|
12
|
+
ba = create_bitarray('int64', [True, False, True])
|
13
|
+
print(type(ba).__name__)
|
14
|
+
# Output: ListInt64BitArray
|
15
|
+
"""
|
2
16
|
|
3
17
|
from __future__ import annotations
|
4
18
|
|
5
|
-
from typing import Dict, Type
|
6
|
-
|
7
19
|
from .bitarray import BitArray
|
8
|
-
from .
|
9
|
-
from .
|
20
|
+
from .bitarray_bigint import BigIntBitArray
|
21
|
+
from .bitarray_bool import ListBoolBitArray
|
22
|
+
from .bitarray_int64 import ListInt64BitArray
|
10
23
|
from .bitarray_mixins import BitArrayCommonMixin
|
11
24
|
|
12
|
-
# Type alias for the default BitArray implementation
|
13
|
-
BitArrayType: Type[BitArray] = ListBitArray
|
14
|
-
|
15
|
-
# Available implementations
|
16
|
-
IMPLEMENTATIONS: Dict[str, Type[BitArray]] = {
|
17
|
-
"list": ListBitArray,
|
18
|
-
"int64": Int64BitArray,
|
19
|
-
}
|
20
|
-
|
21
|
-
|
22
|
-
def create_bitarray(
|
23
|
-
implementation: str = "list", bits: list[bool] | None = None
|
24
|
-
) -> BitArray:
|
25
|
-
"""Factory function to create a BitArray with the specified implementation.
|
26
|
-
|
27
|
-
Args:
|
28
|
-
implementation: The implementation to use ("list" or "int64")
|
29
|
-
bits: Initial list of boolean values
|
30
|
-
|
31
|
-
Returns:
|
32
|
-
BitArray: A BitArray instance using the specified implementation
|
33
|
-
|
34
|
-
Raises:
|
35
|
-
ValueError: If the implementation is not supported
|
36
|
-
"""
|
37
|
-
if implementation not in IMPLEMENTATIONS:
|
38
|
-
raise ValueError(
|
39
|
-
f"Unknown implementation '{implementation}'. "
|
40
|
-
f"Available: {list(IMPLEMENTATIONS.keys())}"
|
41
|
-
)
|
42
|
-
|
43
|
-
return IMPLEMENTATIONS[implementation](bits)
|
44
|
-
|
45
|
-
|
46
|
-
def set_default_implementation(implementation: str) -> None:
|
47
|
-
"""Set the default BitArray implementation.
|
48
|
-
|
49
|
-
Args:
|
50
|
-
implementation: The implementation to use as default ("list" or "int64")
|
51
|
-
|
52
|
-
Raises:
|
53
|
-
ValueError: If the implementation is not supported
|
54
|
-
"""
|
55
|
-
global BitArrayType
|
56
|
-
|
57
|
-
if implementation not in IMPLEMENTATIONS:
|
58
|
-
raise ValueError(
|
59
|
-
f"Unknown implementation '{implementation}'. "
|
60
|
-
f"Available: {list(IMPLEMENTATIONS.keys())}"
|
61
|
-
)
|
62
|
-
|
63
|
-
BitArrayType = IMPLEMENTATIONS[implementation]
|
64
|
-
|
65
|
-
|
66
|
-
def get_available_implementations() -> list[str]:
|
67
|
-
"""Get the list of available BitArray implementations.
|
68
|
-
|
69
|
-
Returns:
|
70
|
-
list[str]: List of available implementation names
|
71
|
-
"""
|
72
|
-
return list(IMPLEMENTATIONS.keys())
|
73
|
-
|
74
|
-
|
75
|
-
# Maintain backward compatibility by exposing the methods as module-level functions
|
76
|
-
def parse_bitarray(bitstring: str) -> BitArray:
|
77
|
-
"""Parse a string of bits (with optional spaces) into a BitArray instance."""
|
78
|
-
return BitArrayType.parse_bitarray(bitstring)
|
79
|
-
|
80
|
-
|
81
25
|
__all__ = [
|
82
26
|
"BitArray",
|
83
|
-
"
|
84
|
-
"
|
27
|
+
"ListBoolBitArray",
|
28
|
+
"ListInt64BitArray",
|
29
|
+
"BigIntBitArray",
|
85
30
|
"BitArrayCommonMixin",
|
86
|
-
"create_bitarray",
|
87
|
-
"set_default_implementation",
|
88
|
-
"get_available_implementations",
|
89
|
-
"parse_bitarray",
|
90
31
|
]
|
flexfloat/bitarray/bitarray.py
CHANGED
@@ -1,8 +1,19 @@
|
|
1
|
-
"""BitArray protocol definition for the flexfloat package.
|
1
|
+
"""BitArray protocol definition for the flexfloat package.
|
2
|
+
|
3
|
+
This module defines the BitArray protocol, which all BitArray implementations must
|
4
|
+
follow. The protocol ensures a consistent interface for bit manipulation.
|
5
|
+
|
6
|
+
Example:
|
7
|
+
from flexfloat.bitarray import BitArray
|
8
|
+
class MyBitArray(BitArray):
|
9
|
+
...
|
10
|
+
my_bitarray = MyBitArray()
|
11
|
+
isinstance(my_bitarray, BitArray) # True
|
12
|
+
"""
|
2
13
|
|
3
14
|
from __future__ import annotations
|
4
15
|
|
5
|
-
from typing import Iterator, Protocol, overload, runtime_checkable
|
16
|
+
from typing import Iterable, Iterator, Protocol, overload, runtime_checkable
|
6
17
|
|
7
18
|
|
8
19
|
@runtime_checkable
|
@@ -11,81 +22,103 @@ class BitArray(Protocol):
|
|
11
22
|
|
12
23
|
This protocol defines all the methods and properties that a BitArray
|
13
24
|
implementation must provide.
|
25
|
+
|
26
|
+
For consistency, all BitArray implementations should order bits as LSB-first,
|
27
|
+
meaning the least significant bit is at index 0 and the most significant bit
|
28
|
+
is at the highest index.
|
14
29
|
"""
|
15
30
|
|
16
|
-
|
17
|
-
|
31
|
+
@classmethod
|
32
|
+
def from_bits(cls, bits: list[bool] | None = None) -> "BitArray":
|
33
|
+
"""Creates a BitArray from a list of boolean values.
|
18
34
|
|
19
35
|
Args:
|
20
|
-
bits:
|
36
|
+
bits (list[bool] | None, optional): List of boolean values. Defaults to
|
37
|
+
None, which creates an empty BitArray.
|
38
|
+
|
39
|
+
Returns:
|
40
|
+
BitArray: A BitArray created from the bits.
|
21
41
|
"""
|
22
42
|
...
|
23
43
|
|
24
44
|
@classmethod
|
25
|
-
def from_float(cls, value: float) -> BitArray:
|
26
|
-
"""
|
45
|
+
def from_float(cls, value: float) -> "BitArray":
|
46
|
+
"""Converts a floating-point number to a bit array.
|
27
47
|
|
28
48
|
Args:
|
29
49
|
value (float): The floating-point number to convert.
|
50
|
+
|
30
51
|
Returns:
|
31
|
-
|
32
|
-
number.
|
52
|
+
BitArray: A BitArray representing the bits of the floating-point number.
|
33
53
|
"""
|
34
54
|
...
|
35
55
|
|
36
56
|
@classmethod
|
37
|
-
def from_signed_int(cls, value: int, length: int) -> BitArray:
|
38
|
-
"""
|
57
|
+
def from_signed_int(cls, value: int, length: int) -> "BitArray":
|
58
|
+
"""Converts a signed integer to a bit array using off-set binary representation.
|
39
59
|
|
40
60
|
Args:
|
41
61
|
value (int): The signed integer to convert.
|
42
62
|
length (int): The length of the resulting bit array.
|
63
|
+
|
43
64
|
Returns:
|
44
|
-
|
65
|
+
BitArray: A BitArray representing the bits of the signed integer.
|
66
|
+
|
45
67
|
Raises:
|
46
68
|
AssertionError: If the value is out of range for the specified length.
|
47
69
|
"""
|
48
70
|
...
|
49
71
|
|
50
72
|
@classmethod
|
51
|
-
def zeros(cls, length: int) -> BitArray:
|
52
|
-
"""
|
73
|
+
def zeros(cls, length: int) -> "BitArray":
|
74
|
+
"""Creates a BitArray filled with zeros.
|
53
75
|
|
54
76
|
Args:
|
55
|
-
length: The length of the bit array.
|
77
|
+
length (int): The length of the bit array.
|
78
|
+
|
56
79
|
Returns:
|
57
|
-
|
80
|
+
BitArray: A BitArray filled with False values.
|
58
81
|
"""
|
59
82
|
...
|
60
83
|
|
61
84
|
@classmethod
|
62
|
-
def ones(cls, length: int) -> BitArray:
|
63
|
-
"""
|
85
|
+
def ones(cls, length: int) -> "BitArray":
|
86
|
+
"""Creates a BitArray filled with ones.
|
64
87
|
|
65
88
|
Args:
|
66
|
-
length: The length of the bit array.
|
89
|
+
length (int): The length of the bit array.
|
90
|
+
|
67
91
|
Returns:
|
68
|
-
|
92
|
+
BitArray: A BitArray filled with True values.
|
69
93
|
"""
|
70
94
|
...
|
71
95
|
|
72
|
-
@
|
73
|
-
def parse_bitarray(bitstring: str) -> BitArray:
|
74
|
-
"""
|
96
|
+
@classmethod
|
97
|
+
def parse_bitarray(cls, bitstring: Iterable[str]) -> "BitArray":
|
98
|
+
"""Parses a string of bits (with optional spaces) into a BitArray instance.
|
99
|
+
Non-valid characters are ignored.
|
100
|
+
|
101
|
+
Args:
|
102
|
+
bitstring (Iterable[str]): A string of bits, e.g., "1010 1100".
|
103
|
+
|
104
|
+
Returns:
|
105
|
+
BitArray: A BitArray instance created from the bit string.
|
106
|
+
"""
|
75
107
|
...
|
76
108
|
|
77
109
|
def to_float(self) -> float:
|
78
|
-
"""
|
110
|
+
"""Converts a 64-bit array to a floating-point number.
|
79
111
|
|
80
112
|
Returns:
|
81
113
|
float: The floating-point number represented by the bit array.
|
114
|
+
|
82
115
|
Raises:
|
83
116
|
AssertionError: If the bit array is not 64 bits long.
|
84
117
|
"""
|
85
118
|
...
|
86
119
|
|
87
120
|
def to_int(self) -> int:
|
88
|
-
"""
|
121
|
+
"""Converts the bit array to an unsigned integer.
|
89
122
|
|
90
123
|
Returns:
|
91
124
|
int: The integer represented by the bit array.
|
@@ -93,18 +126,19 @@ class BitArray(Protocol):
|
|
93
126
|
...
|
94
127
|
|
95
128
|
def to_signed_int(self) -> int:
|
96
|
-
"""
|
129
|
+
"""Converts a bit array into a signed integer using off-set binary
|
97
130
|
representation.
|
98
131
|
|
99
132
|
Returns:
|
100
133
|
int: The signed integer represented by the bit array.
|
134
|
+
|
101
135
|
Raises:
|
102
136
|
AssertionError: If the bit array is empty.
|
103
137
|
"""
|
104
138
|
...
|
105
139
|
|
106
|
-
def shift(self, shift_amount: int, fill: bool = False) -> BitArray:
|
107
|
-
"""
|
140
|
+
def shift(self, shift_amount: int, fill: bool = False) -> "BitArray":
|
141
|
+
"""Shifts the bit array left or right by a specified number of bits.
|
108
142
|
|
109
143
|
This function shifts the bits in the array, filling in new bits with the
|
110
144
|
specified fill value.
|
@@ -114,85 +148,151 @@ class BitArray(Protocol):
|
|
114
148
|
Args:
|
115
149
|
shift_amount (int): The number of bits to shift. Positive for left shift,
|
116
150
|
negative for right shift.
|
117
|
-
fill (bool): The value to fill in the new bits created by the
|
118
|
-
Defaults to False.
|
151
|
+
fill (bool, optional): The value to fill in the new bits created by the
|
152
|
+
shift. Defaults to False.
|
153
|
+
|
119
154
|
Returns:
|
120
|
-
|
155
|
+
BitArray: A new BitArray with the bits shifted and filled.
|
121
156
|
"""
|
122
157
|
...
|
123
158
|
|
124
|
-
def copy(self) -> BitArray:
|
125
|
-
"""
|
159
|
+
def copy(self) -> "BitArray":
|
160
|
+
"""Creates a copy of the bit array.
|
126
161
|
|
127
162
|
Returns:
|
128
|
-
|
163
|
+
BitArray: A new BitArray with the same bits.
|
129
164
|
"""
|
130
165
|
...
|
131
166
|
|
132
167
|
def __len__(self) -> int:
|
133
|
-
"""
|
168
|
+
"""Returns the length of the bit array.
|
169
|
+
|
170
|
+
Returns:
|
171
|
+
int: The number of bits in the array.
|
172
|
+
"""
|
134
173
|
...
|
135
174
|
|
136
175
|
@overload
|
137
176
|
def __getitem__(self, index: int) -> bool: ...
|
138
177
|
@overload
|
139
|
-
def __getitem__(self, index: slice) -> BitArray: ...
|
178
|
+
def __getitem__(self, index: slice) -> "BitArray": ...
|
140
179
|
|
141
180
|
def __getitem__(self, index: int | slice) -> bool | BitArray:
|
142
|
-
"""Get
|
181
|
+
"""Get a bit or a slice of bits as a new BitArray."""
|
143
182
|
...
|
144
183
|
|
145
184
|
@overload
|
146
185
|
def __setitem__(self, index: int, value: bool) -> None: ...
|
147
186
|
@overload
|
148
|
-
def __setitem__(self, index: slice, value: BitArray | list[bool]) -> None: ...
|
187
|
+
def __setitem__(self, index: slice, value: "BitArray" | list[bool]) -> None: ...
|
149
188
|
|
150
189
|
def __setitem__(
|
151
|
-
self, index: int | slice, value: bool | list[bool] | BitArray
|
190
|
+
self, index: int | slice, value: bool | list[bool] | "BitArray"
|
152
191
|
) -> None:
|
153
|
-
"""
|
192
|
+
"""Sets an item or slice in the bit array.
|
193
|
+
|
194
|
+
Args:
|
195
|
+
index (int or slice): The index or slice to set.
|
196
|
+
value (bool or list[bool] or BitArray): The value(s) to assign.
|
197
|
+
"""
|
154
198
|
...
|
155
199
|
|
156
200
|
def __iter__(self) -> Iterator[bool]:
|
157
|
-
"""
|
201
|
+
"""Iterates over the bits in the array.
|
202
|
+
|
203
|
+
Yields:
|
204
|
+
bool: The next bit in the array.
|
205
|
+
"""
|
158
206
|
...
|
159
207
|
|
160
|
-
def __add__(self, other: BitArray | list[bool]) -> BitArray:
|
161
|
-
"""
|
208
|
+
def __add__(self, other: "BitArray" | list[bool]) -> "BitArray":
|
209
|
+
"""Concatenates two bit arrays.
|
210
|
+
|
211
|
+
Args:
|
212
|
+
other (BitArray or list[bool]): The other bit array or list to concatenate.
|
213
|
+
|
214
|
+
Returns:
|
215
|
+
BitArray: The concatenated bit array.
|
216
|
+
"""
|
162
217
|
...
|
163
218
|
|
164
|
-
def __radd__(self, other: list[bool]) -> BitArray:
|
165
|
-
"""Reverse concatenation with a list.
|
219
|
+
def __radd__(self, other: list[bool]) -> "BitArray":
|
220
|
+
"""Reverse concatenation with a list.
|
221
|
+
|
222
|
+
Args:
|
223
|
+
other (list[bool]): The list to concatenate before this bit array.
|
224
|
+
|
225
|
+
Returns:
|
226
|
+
BitArray: The concatenated bit array.
|
227
|
+
"""
|
166
228
|
...
|
167
229
|
|
168
230
|
def __eq__(self, other: object) -> bool:
|
169
|
-
"""
|
231
|
+
"""Checks equality with another BitArray or list.
|
232
|
+
|
233
|
+
Args:
|
234
|
+
other (object): The object to compare with.
|
235
|
+
|
236
|
+
Returns:
|
237
|
+
bool: True if equal, False otherwise.
|
238
|
+
"""
|
170
239
|
...
|
171
240
|
|
172
241
|
def __bool__(self) -> bool:
|
173
|
-
"""
|
242
|
+
"""Returns True if any bit is set.
|
243
|
+
|
244
|
+
Returns:
|
245
|
+
bool: True if any bit is set, False otherwise.
|
246
|
+
"""
|
174
247
|
...
|
175
248
|
|
176
249
|
def __repr__(self) -> str:
|
177
|
-
"""
|
250
|
+
"""Returns a string representation of the BitArray.
|
251
|
+
|
252
|
+
Returns:
|
253
|
+
str: String representation of the BitArray.
|
254
|
+
"""
|
178
255
|
...
|
179
256
|
|
180
257
|
def __str__(self) -> str:
|
181
|
-
"""
|
258
|
+
"""Returns a string representation of the bits.
|
259
|
+
|
260
|
+
Returns:
|
261
|
+
str: String representation of the bits.
|
262
|
+
"""
|
182
263
|
...
|
183
264
|
|
184
265
|
def any(self) -> bool:
|
185
|
-
"""
|
266
|
+
"""Returns True if any bit is set to True.
|
267
|
+
|
268
|
+
Returns:
|
269
|
+
bool: True if any bit is set to True, False otherwise.
|
270
|
+
"""
|
186
271
|
...
|
187
272
|
|
188
273
|
def all(self) -> bool:
|
189
|
-
"""
|
274
|
+
"""Returns True if all bits are set to True.
|
275
|
+
|
276
|
+
Returns:
|
277
|
+
bool: True if all bits are set to True, False otherwise.
|
278
|
+
"""
|
190
279
|
...
|
191
280
|
|
192
281
|
def count(self, value: bool = True) -> int:
|
193
|
-
"""
|
282
|
+
"""Counts the number of bits set to the specified value.
|
283
|
+
|
284
|
+
Args:
|
285
|
+
value (bool, optional): The value to count. Defaults to True.
|
286
|
+
|
287
|
+
Returns:
|
288
|
+
int: The number of bits set to the specified value.
|
289
|
+
"""
|
194
290
|
...
|
195
291
|
|
196
|
-
def reverse(self) -> BitArray:
|
197
|
-
"""
|
292
|
+
def reverse(self) -> "BitArray":
|
293
|
+
"""Returns a new BitArray with the bits in reverse order.
|
294
|
+
|
295
|
+
Returns:
|
296
|
+
BitArray: A new BitArray with the bits in reverse order.
|
297
|
+
"""
|
198
298
|
...
|