flexfloat 0.1.3__py3-none-any.whl → 0.3.0__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/types.py CHANGED
@@ -1,4 +1,10 @@
1
- """Type definitions for the flexfloat package."""
1
+ """Type definitions for the flexfloat package.
2
+
3
+ This module provides type aliases used throughout the flexfloat package.
4
+
5
+ Type Aliases:
6
+ Number: Alias for int | float, used for numeric arguments.
7
+ """
2
8
 
3
9
  from typing import TypeAlias
4
10
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flexfloat
3
- Version: 0.1.3
3
+ Version: 0.3.0
4
4
  Summary: A library for arbitrary precision floating point arithmetic
5
5
  Author: Ferran Sanchez Llado
6
6
  License: MIT
@@ -45,7 +45,7 @@ A high-precision Python library for arbitrary precision floating-point arithmeti
45
45
  - **🔢 Growable Exponents**: Dynamically expand exponent size to handle extremely large (>10^308) or small (<10^-308) numbers
46
46
  - **🎯 Fixed-Size Fractions**: Maintain IEEE 754-compatible 52-bit fraction precision for consistent accuracy
47
47
  - **⚡ Full Arithmetic Support**: Addition, subtraction, multiplication, division, and power operations
48
- - **🔧 Multiple BitArray Backends**: Choose between list-based and int64-based implementations for optimal performance
48
+ - **🔧 Multiple BitArray Backends**: Choose between bool-list, int64-list, and big-integer implementations for optimal performance
49
49
  - **🌟 Special Value Handling**: Complete support for NaN, ±infinity, and zero values
50
50
  - **🛡️ Overflow Protection**: Automatic exponent growth prevents overflow/underflow errors
51
51
  - **📊 IEEE 754 Baseline**: Fully compatible with standard double-precision format as the starting point
@@ -81,12 +81,15 @@ print(f"Exponent bits: {len(large_result.exponent)}") # > 11 (grown beyond IEEE
81
81
  print(f"Can represent: {large_result}") # No overflow!
82
82
  ```
83
83
 
84
- ### Advanced Examples
84
+ ### Advanced Features
85
85
 
86
86
  ```python
87
- from flexfloat import FlexFloat
87
+ from flexfloat import FlexFloat, BigIntBitArray
88
+
89
+ # Use different BitArray implementations for specific needs
90
+ FlexFloat.set_bitarray_implementation(BigIntBitArray)
88
91
 
89
- # Mathematical operations
92
+ # Mathematical operations with unlimited precision
90
93
  x = FlexFloat.from_float(2.0)
91
94
  y = FlexFloat.from_float(3.0)
92
95
 
@@ -98,10 +101,13 @@ print(power_result.to_float()) # 8.0
98
101
  e_result = FlexFloat.e ** x # e^2
99
102
  print(f"e^2 ≈ {e_result.to_float()}")
100
103
 
104
+ # Absolute value operations
105
+ abs_result = abs(FlexFloat.from_float(-42.0))
106
+ print(f"|-42| = {abs_result.to_float()}") # 42.0
107
+
101
108
  # Working with extreme values
102
- tiny = FlexFloat.from_float(1e-300)
103
109
  huge = FlexFloat.from_float(1e300)
104
- extreme_product = tiny * huge
110
+ extreme_product = huge * huge
105
111
  print(f"Product: {extreme_product.to_float()}") # Still computable!
106
112
 
107
113
  # Precision demonstration
@@ -111,35 +117,40 @@ print(f"1/3 with 52-bit precision: {precise_calc}")
111
117
 
112
118
  ## 🔧 BitArray Backends
113
119
 
114
- FlexFloat supports multiple BitArray implementations for different performance characteristics:
120
+ FlexFloat supports multiple BitArray implementations for different performance characteristics. You can use them directly or configure FlexFloat to use a specific implementation:
115
121
 
116
122
  ```python
117
123
  from flexfloat import (
118
124
  FlexFloat,
119
- set_default_implementation,
120
- get_available_implementations
125
+ ListBoolBitArray,
126
+ ListInt64BitArray,
127
+ BigIntBitArray
121
128
  )
122
129
 
123
- # View available implementations
124
- print(get_available_implementations()) # ['list', 'int64']
125
-
126
- # Use list-based implementation (default, more flexible)
127
- set_default_implementation('list')
128
- flex_list = FlexFloat.from_float(42.0)
130
+ # Configure FlexFloat to use a specific BitArray implementation
131
+ FlexFloat.set_bitarray_implementation(ListBoolBitArray) # Default
132
+ flex_bool = FlexFloat.from_float(42.0)
129
133
 
130
- # Use int64-based implementation (faster for small bit arrays)
131
- set_default_implementation('int64')
134
+ FlexFloat.set_bitarray_implementation(ListInt64BitArray) # For performance
132
135
  flex_int64 = FlexFloat.from_float(42.0)
133
136
 
134
- # Both produce the same results with different performance characteristics
137
+ FlexFloat.set_bitarray_implementation(BigIntBitArray) # For very large arrays
138
+ flex_bigint = FlexFloat.from_float(42.0)
139
+
140
+ # Use BitArray implementations directly
141
+ bits = [True, False, True, False]
142
+ bool_array = ListBoolBitArray.from_bits(bits)
143
+ int64_array = ListInt64BitArray.from_bits(bits)
144
+ bigint_array = BigIntBitArray.from_bits(bits)
135
145
  ```
136
146
 
137
147
  ### Implementation Comparison
138
148
 
139
149
  | Implementation | Best For | Pros | Cons |
140
150
  |---------------|----------|------|------|
141
- | `list[bool]` | Smaller exponents and testing | Flexible, easy to understand | Slower for large numbers |
142
- | `list[int64]` | Standard operations | Fast for bigger numbers, efficient memory | Overhead for small numbers |
151
+ | `ListBoolBitArray` | Testing and development | Simple, flexible, easy to debug | Slower for large operations |
152
+ | `ListInt64BitArray` | Standard operations | Fast for medium-sized arrays, memory efficient | Some overhead for very small arrays |
153
+ | `BigIntBitArray` | Any usescases | Python already optimizes it | Overhead for small arrays |
143
154
 
144
155
  ## 📚 API Reference
145
156
 
@@ -159,6 +170,11 @@ abs(a), -a
159
170
 
160
171
  # Mathematical functions
161
172
  FlexFloat.e ** x # Exponential function
173
+ flexfloat.exp() # Natural exponential
174
+ flexfloat.abs() # Absolute value
175
+
176
+ # BitArray configuration
177
+ FlexFloat.set_bitarray_implementation(implementation: Type[BitArray])
162
178
  ```
163
179
 
164
180
  ### Special Values
@@ -269,8 +285,9 @@ flexfloat/
269
285
  ├── types.py # Type definitions
270
286
  ├── bitarray/ # BitArray implementations
271
287
  │ ├── bitarray.py # Abstract base class
272
- │ ├── bitarray_list.py # List-based implementation
273
- │ ├── bitarray_int64.py # Int64-based implementation
288
+ │ ├── bitarray_bool.py # List[bool] implementation
289
+ │ ├── bitarray_int64.py # List[int64] implementation
290
+ │ ├── bitarray_bigint.py # Python int implementation
274
291
  │ └── bitarray_mixins.py # Common functionality
275
292
  └── __init__.py # Public API exports
276
293
  ```
@@ -301,8 +318,14 @@ flexfloat/
301
318
  ### Optimization Tips
302
319
 
303
320
  ```python
304
- # Prefer int64 implementation for standard operations
305
- set_default_implementation('int64')
321
+ from flexfloat import FlexFloat, ListInt64BitArray, BigIntBitArray
322
+
323
+ # Choose the right BitArray implementation for your use case
324
+ # For standard operations with moderate precision
325
+ FlexFloat.set_bitarray_implementation(ListInt64BitArray)
326
+
327
+ # For most use cases, Python's int is already optimized
328
+ FlexFloat.set_bitarray_implementation(BigIntBitArray)
306
329
 
307
330
  # Batch operations when possible
308
331
  values = [FlexFloat.from_float(x) for x in range(1000)]
@@ -0,0 +1,15 @@
1
+ flexfloat/__init__.py,sha256=Y7oR-CRyfDv_ImzcS4jkVveMzaXc2BHvAyzItgUaF3E,933
2
+ flexfloat/core.py,sha256=EQiBMmUtDreWFLjVeuaEiEj-PyNNcOV9BmRtOCs4neU,42821
3
+ flexfloat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ flexfloat/types.py,sha256=Enm4-oyGnvxGI-7MOK6eEIH2IzWafk0wQBsPaTqFYrE,266
5
+ flexfloat/bitarray/__init__.py,sha256=aFnw7HSlFwWnFwmLhmjvRwt6qOakbUochHwT8di0v14,979
6
+ flexfloat/bitarray/bitarray.py,sha256=L8CYFSxyMgfV-CpvtrKJ_kO3nexsHK2E2pNN9BfnNyI,8428
7
+ flexfloat/bitarray/bitarray_bigint.py,sha256=yLfAreZ9hhP2f2dIS7ptYSuAFlUTXJiv-LtHhRWN5dc,9986
8
+ flexfloat/bitarray/bitarray_bool.py,sha256=naTUcTycvP9BfU1_CJRgajgvsJoQz9jvi5aI224pphE,6429
9
+ flexfloat/bitarray/bitarray_int64.py,sha256=FLfbg2gk_Ia-9_4UjoiWYZNK3CbD4teAYU5SGSV3WF0,10856
10
+ flexfloat/bitarray/bitarray_mixins.py,sha256=HJkyseP_yat0tE3_XElFEqBgKk8oWEiHEKjzqIRwUnw,5026
11
+ flexfloat-0.3.0.dist-info/licenses/LICENSE,sha256=uwwkK--SUYUV3lbrv9kXJ_vDiYfHVb-t732g6c4qg7Q,1077
12
+ flexfloat-0.3.0.dist-info/METADATA,sha256=l9sXHmygreTApX2unPPQny_I8vVekmGUl-A0SLcbXSU,11510
13
+ flexfloat-0.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
+ flexfloat-0.3.0.dist-info/top_level.txt,sha256=82S8dY2UoNZh-9pwg7tUvbwB3uw2s3mfEoyUW6vCMdU,10
15
+ flexfloat-0.3.0.dist-info/RECORD,,
@@ -1,187 +0,0 @@
1
- """List-based BitArray implementation for the flexfloat package."""
2
-
3
- from __future__ import annotations
4
-
5
- import struct
6
- from typing import Iterator, overload
7
-
8
- from .bitarray import BitArray
9
- from .bitarray_mixins import BitArrayCommonMixin
10
-
11
-
12
- class ListBitArray(BitArrayCommonMixin):
13
- """A bit array class that encapsulates a list of booleans with utility methods.
14
-
15
- This class provides all the functionality previously available through utility
16
- functions, now encapsulated as methods for better object-oriented design.
17
- """
18
-
19
- def __init__(self, bits: list[bool] | None = None):
20
- """Initialize a BitArray.
21
-
22
- Args:
23
- bits: Initial list of boolean values. Defaults to empty list.
24
- """
25
- self._bits = bits if bits is not None else []
26
-
27
- @classmethod
28
- def zeros(cls, length: int) -> ListBitArray:
29
- """Create a BitArray filled with zeros.
30
-
31
- Args:
32
- length: The length of the bit array.
33
- Returns:
34
- ListBitArray: A BitArray filled with False values.
35
- """
36
- return cls([False] * length)
37
-
38
- @classmethod
39
- def ones(cls, length: int) -> ListBitArray:
40
- """Create a BitArray filled with ones.
41
-
42
- Args:
43
- length: The length of the bit array.
44
- Returns:
45
- ListBitArray: A BitArray filled with True values.
46
- """
47
- return cls([True] * length)
48
-
49
- @staticmethod
50
- def parse_bitarray(bitstring: str) -> ListBitArray:
51
- """Parse a string of bits (with optional spaces) into a BitArray instance."""
52
- bits = [c == "1" for c in bitstring if c in "01"]
53
- return ListBitArray(bits)
54
-
55
- def to_float(self) -> float:
56
- """Convert a 64-bit array to a floating-point number.
57
-
58
- Returns:
59
- float: The floating-point number represented by the bit array.
60
- Raises:
61
- AssertionError: If the bit array is not 64 bits long.
62
- """
63
- assert len(self._bits) == 64, "Bit array must be 64 bits long."
64
-
65
- byte_values = bytearray()
66
- for i in range(0, 64, 8):
67
- byte = 0
68
- for j in range(8):
69
- if self._bits[i + j]:
70
- byte |= 1 << (7 - j)
71
- byte_values.append(byte)
72
- # Unpack as double precision (64 bits)
73
- return struct.unpack("!d", bytes(byte_values))[0] # type: ignore
74
-
75
- def to_int(self) -> int:
76
- """Convert the bit array to an unsigned integer.
77
-
78
- Returns:
79
- int: The integer represented by the bit array.
80
- """
81
- return sum((1 << i) for i, bit in enumerate(reversed(self._bits)) if bit)
82
-
83
- def to_signed_int(self) -> int:
84
- """Convert a bit array into a signed integer using off-set binary
85
- representation.
86
-
87
- Returns:
88
- int: The signed integer represented by the bit array.
89
- Raises:
90
- AssertionError: If the bit array is empty.
91
- """
92
- assert len(self._bits) > 0, "Bit array must not be empty."
93
-
94
- int_value = self.to_int()
95
- # Half of the maximum value
96
- bias = 1 << (len(self._bits) - 1)
97
- # If the sign bit is set, subtract the bias
98
- return int_value - bias
99
-
100
- def shift(self, shift_amount: int, fill: bool = False) -> ListBitArray:
101
- """Shift the bit array left or right by a specified number of bits.
102
-
103
- This function shifts the bits in the array, filling in new bits with the
104
- specified fill value.
105
- If the value is positive, it shifts left; if negative, it shifts right.
106
- Fills the new bits with the specified fill value (default is False).
107
-
108
- Args:
109
- shift_amount (int): The number of bits to shift. Positive for left shift,
110
- negative for right shift.
111
- fill (bool): The value to fill in the new bits created by the shift.
112
- Defaults to False.
113
- Returns:
114
- ListBitArray: A new BitArray with the bits shifted and filled.
115
- """
116
- if shift_amount == 0:
117
- return self.copy()
118
- if abs(shift_amount) > len(self._bits):
119
- new_bits = [fill] * len(self._bits)
120
- elif shift_amount > 0:
121
- new_bits = [fill] * shift_amount + self._bits[:-shift_amount]
122
- else:
123
- new_bits = self._bits[-shift_amount:] + [fill] * (-shift_amount)
124
- return ListBitArray(new_bits)
125
-
126
- def copy(self) -> ListBitArray:
127
- """Create a copy of the bit array.
128
-
129
- Returns:
130
- ListBitArray: A new BitArray with the same bits.
131
- """
132
- return ListBitArray(self._bits.copy())
133
-
134
- def __len__(self) -> int:
135
- """Return the length of the bit array."""
136
- return len(self._bits)
137
-
138
- @overload
139
- def __getitem__(self, index: int) -> bool: ...
140
- @overload
141
- def __getitem__(self, index: slice) -> ListBitArray: ...
142
-
143
- def __getitem__(self, index: int | slice) -> bool | ListBitArray:
144
- """Get an item or slice from the bit array."""
145
- if isinstance(index, slice):
146
- return ListBitArray(self._bits[index])
147
- return self._bits[index]
148
-
149
- @overload
150
- def __setitem__(self, index: int, value: bool) -> None: ...
151
- @overload
152
- def __setitem__(self, index: slice, value: BitArray | list[bool]) -> None: ...
153
-
154
- def __setitem__(
155
- self, index: int | slice, value: bool | list[bool] | BitArray
156
- ) -> None:
157
- """Set an item or slice in the bit array."""
158
- if isinstance(index, slice):
159
- if isinstance(value, BitArray):
160
- self._bits[index] = list(value)
161
- elif isinstance(value, list):
162
- self._bits[index] = value
163
- else:
164
- raise TypeError("Cannot assign a single bool to a slice")
165
- return
166
- if isinstance(value, bool):
167
- self._bits[index] = value
168
- else:
169
- raise TypeError("Cannot assign a list or BitArray to a single index")
170
-
171
- def __iter__(self) -> Iterator[bool]:
172
- """Iterate over the bits in the array."""
173
- return iter(self._bits)
174
-
175
- def __add__(self, other: BitArray | list[bool]) -> ListBitArray:
176
- """Concatenate two bit arrays."""
177
- if isinstance(other, BitArray):
178
- return ListBitArray(self._bits + list(other))
179
- return ListBitArray(self._bits + other)
180
-
181
- def __radd__(self, other: list[bool]) -> ListBitArray:
182
- """Reverse concatenation with a list."""
183
- return ListBitArray(other + self._bits)
184
-
185
- def __repr__(self) -> str:
186
- """Return a string representation of the BitArray."""
187
- return f"ListBitArray({self._bits})"
@@ -1,14 +0,0 @@
1
- flexfloat/__init__.py,sha256=QynzrIicNr9asICyJbity5QdrFop7xEDlKkrS7rZfKk,725
2
- flexfloat/core.py,sha256=u5TVNxGxsb0_H4vc9p6PvjeBYRJrYBABhZxOTcS5sAg,39658
3
- flexfloat/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- flexfloat/types.py,sha256=_vRC7gQl5ua76QfKco4L3jQ4uPtEPUxPNGy4zWBFbns,113
5
- flexfloat/bitarray/__init__.py,sha256=nyHA70JnEuDVOYWfHjhNNu0zm4xVLWADkuMo0kqsJ7c,2512
6
- flexfloat/bitarray/bitarray.py,sha256=ASq8L1Ky84H41AzhLlZjY1u1k6zOtyf2czuD-ixGsJA,5912
7
- flexfloat/bitarray/bitarray_int64.py,sha256=kq-vULiA0lk8GaSDUf9U41q12qCREdn83ywKxiNjv_M,10585
8
- flexfloat/bitarray/bitarray_list.py,sha256=OTH6MjA1kBHPZP2Mi2mIViN2aOdxHVVrCybV-9ko99c,6586
9
- flexfloat/bitarray/bitarray_mixins.py,sha256=Cfm0dt1gRIG5kNb9wPPH62Tzd5B0Ck6YZupHia1jKmo,3302
10
- flexfloat-0.1.3.dist-info/licenses/LICENSE,sha256=uwwkK--SUYUV3lbrv9kXJ_vDiYfHVb-t732g6c4qg7Q,1077
11
- flexfloat-0.1.3.dist-info/METADATA,sha256=Iea-nvdjZCsfvrhfNQTEHnCozLgPLRotRG8RqskwjXs,10375
12
- flexfloat-0.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
13
- flexfloat-0.1.3.dist-info/top_level.txt,sha256=82S8dY2UoNZh-9pwg7tUvbwB3uw2s3mfEoyUW6vCMdU,10
14
- flexfloat-0.1.3.dist-info/RECORD,,