flexfloat 0.1.2__tar.gz → 0.1.5__tar.gz
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-0.1.2 → flexfloat-0.1.5}/.bumpversion.cfg +1 -1
- {flexfloat-0.1.2 → flexfloat-0.1.5}/.github/workflows/manual-release.yml +1 -4
- {flexfloat-0.1.2 → flexfloat-0.1.5}/.github/workflows/pr-labeler.yml +11 -3
- flexfloat-0.1.5/.github/workflows/release.yml +87 -0
- flexfloat-0.1.5/.github/workflows/version-bump.yml +121 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/.github/workflows/version-check.yml +4 -1
- flexfloat-0.1.5/PKG-INFO +340 -0
- flexfloat-0.1.5/README.md +306 -0
- flexfloat-0.1.5/flexfloat/__init__.py +36 -0
- flexfloat-0.1.5/flexfloat/bitarray/__init__.py +31 -0
- flexfloat-0.1.5/flexfloat/bitarray/bitarray.py +298 -0
- flexfloat-0.1.5/flexfloat/bitarray/bitarray_bigint.py +305 -0
- flexfloat-0.1.5/flexfloat/bitarray/bitarray_bool.py +202 -0
- flexfloat-0.1.5/flexfloat/bitarray/bitarray_int64.py +333 -0
- flexfloat-0.1.5/flexfloat/bitarray/bitarray_mixins.py +156 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/flexfloat/core.py +482 -94
- flexfloat-0.1.5/flexfloat/types.py +11 -0
- flexfloat-0.1.5/flexfloat.egg-info/PKG-INFO +340 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/flexfloat.egg-info/SOURCES.txt +11 -2
- {flexfloat-0.1.2 → flexfloat-0.1.5}/pyproject.toml +1 -1
- {flexfloat-0.1.2 → flexfloat-0.1.5}/scripts/validate_cicd.py +2 -1
- {flexfloat-0.1.2 → flexfloat-0.1.5}/scripts/version_manager.py +2 -3
- flexfloat-0.1.5/tests/__init__.py +27 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/tests/test_addition.py +19 -21
- flexfloat-0.1.5/tests/test_bigint_bitarray.py +409 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/tests/test_bitarray.py +63 -55
- flexfloat-0.1.5/tests/test_bitarray_implementations.py +336 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/tests/test_conversions.py +31 -31
- {flexfloat-0.1.2 → flexfloat-0.1.5}/tests/test_division.py +17 -41
- flexfloat-0.1.2/tests/test_bigfloat.py → flexfloat-0.1.5/tests/test_flexfloat.py +61 -15
- {flexfloat-0.1.2 → flexfloat-0.1.5}/tests/test_multiplication.py +20 -23
- flexfloat-0.1.5/tests/test_power.py +488 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/tests/test_str_representation.py +6 -6
- {flexfloat-0.1.2 → flexfloat-0.1.5}/tests/test_subtraction.py +18 -19
- flexfloat-0.1.2/.github/workflows/release.yml +0 -146
- flexfloat-0.1.2/PKG-INFO +0 -147
- flexfloat-0.1.2/README.md +0 -113
- flexfloat-0.1.2/flexfloat/__init__.py +0 -13
- flexfloat-0.1.2/flexfloat/bitarray.py +0 -257
- flexfloat-0.1.2/flexfloat/types.py +0 -5
- flexfloat-0.1.2/flexfloat.egg-info/PKG-INFO +0 -147
- flexfloat-0.1.2/tests/__init__.py +0 -7
- {flexfloat-0.1.2 → flexfloat-0.1.5}/.github/workflows/build-check.yml +0 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/.github/workflows/test.yml +0 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/.gitignore +0 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/LICENSE +0 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/MANIFEST.in +0 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/flexfloat/py.typed +0 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/flexfloat.egg-info/dependency_links.txt +0 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/flexfloat.egg-info/requires.txt +0 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/flexfloat.egg-info/top_level.txt +0 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/setup.cfg +0 -0
- {flexfloat-0.1.2 → flexfloat-0.1.5}/setup.py +0 -0
@@ -70,9 +70,6 @@ jobs:
|
|
70
70
|
- name: Bump or set version
|
71
71
|
id: bump_version
|
72
72
|
run: |
|
73
|
-
# Update current version in .bumpversion.cfg
|
74
|
-
# sed -i "s/current_version = .*/current_version = ${{ steps.current_version.outputs.version }}/" .bumpversion.cfg
|
75
|
-
|
76
73
|
if [ -n "${{ steps.set_new_version.outputs.new_version }}" ]; then
|
77
74
|
# Set version directly
|
78
75
|
bump2version --new-version ${{ steps.set_new_version.outputs.new_version }} patch
|
@@ -97,7 +94,7 @@ jobs:
|
|
97
94
|
|
98
95
|
- name: Commit version bump
|
99
96
|
run: |
|
100
|
-
git add pyproject.toml flexfloat/__init__.py
|
97
|
+
git add pyproject.toml flexfloat/__init__.py .bumpversion.cfg
|
101
98
|
git commit -m "Bump version to ${{ steps.bump_version.outputs.new_version }} [skip ci]"
|
102
99
|
git push origin main
|
103
100
|
|
@@ -10,6 +10,7 @@ jobs:
|
|
10
10
|
permissions:
|
11
11
|
pull-requests: write
|
12
12
|
contents: read
|
13
|
+
issues: write
|
13
14
|
|
14
15
|
steps:
|
15
16
|
- name: Checkout code
|
@@ -66,7 +67,7 @@ jobs:
|
|
66
67
|
}
|
67
68
|
}
|
68
69
|
|
69
|
-
// Add the
|
70
|
+
// Add only the version bump label
|
70
71
|
await github.rest.issues.addLabels({
|
71
72
|
owner: context.repo.owner,
|
72
73
|
repo: context.repo.repo,
|
@@ -92,12 +93,19 @@ jobs:
|
|
92
93
|
| minor | New features, non-breaking changes |
|
93
94
|
| major | Breaking changes, major updates |
|
94
95
|
|
95
|
-
|
96
|
+
**🚀 Release Status**: This PR is labeled with the recommended version bump type. To trigger a release:
|
97
|
+
1. **Add the \`release\` label** to this PR when ready
|
98
|
+
2. The version will be automatically bumped when the \`release\` label is added
|
99
|
+
3. When merged, it will create a Git tag, GitHub release, and publish to PyPI
|
100
|
+
|
101
|
+
**To prevent release**: Simply don\'t add the \`release\` label.
|
102
|
+
|
103
|
+
**To change version bump**: You can manually change the version bump label:
|
96
104
|
- Add \`major\` label for breaking changes
|
97
105
|
- Add \`minor\` label for new features
|
98
106
|
- Add \`patch\` label for bug fixes
|
99
107
|
|
100
|
-
The version will be automatically updated
|
108
|
+
The version will be automatically updated when the \`release\` label is added to this PR.`;
|
101
109
|
|
102
110
|
// Check if we already commented
|
103
111
|
const comments = await github.rest.issues.listComments({
|
@@ -0,0 +1,87 @@
|
|
1
|
+
name: Release
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request:
|
5
|
+
types: [closed]
|
6
|
+
branches: [main]
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
release:
|
10
|
+
if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'release')
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
permissions:
|
13
|
+
contents: write
|
14
|
+
id-token: write # For trusted publishing to PyPI
|
15
|
+
|
16
|
+
steps:
|
17
|
+
- name: Checkout code
|
18
|
+
uses: actions/checkout@v4
|
19
|
+
with:
|
20
|
+
fetch-depth: 0
|
21
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
22
|
+
|
23
|
+
- name: Set up Python
|
24
|
+
uses: actions/setup-python@v5
|
25
|
+
with:
|
26
|
+
python-version: "3.11"
|
27
|
+
|
28
|
+
- name: Install dependencies
|
29
|
+
run: |
|
30
|
+
python -m pip install --upgrade pip
|
31
|
+
pip install build twine bump2version
|
32
|
+
|
33
|
+
- name: Configure Git
|
34
|
+
run: |
|
35
|
+
git config --local user.email "action@github.com"
|
36
|
+
git config --local user.name "GitHub Action"
|
37
|
+
|
38
|
+
- name: Get current version
|
39
|
+
id: current_version
|
40
|
+
run: |
|
41
|
+
VERSION=$(grep -E '^version = ' pyproject.toml | cut -d'"' -f2)
|
42
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
43
|
+
echo "Current version: $VERSION"
|
44
|
+
|
45
|
+
- name: Run tests
|
46
|
+
run: |
|
47
|
+
pip install -e ".[dev]"
|
48
|
+
pytest tests/
|
49
|
+
|
50
|
+
- name: Build package
|
51
|
+
run: |
|
52
|
+
python -m build
|
53
|
+
|
54
|
+
- name: Create Git tag
|
55
|
+
run: |
|
56
|
+
git tag -a "v${{ steps.current_version.outputs.version }}" -m "Release v${{ steps.current_version.outputs.version }}"
|
57
|
+
git push origin "v${{ steps.current_version.outputs.version }}"
|
58
|
+
|
59
|
+
- name: Create GitHub Release
|
60
|
+
id: create_release
|
61
|
+
uses: softprops/action-gh-release@v2
|
62
|
+
with:
|
63
|
+
tag_name: "v${{ steps.current_version.outputs.version }}"
|
64
|
+
name: "Release v${{ steps.current_version.outputs.version }}"
|
65
|
+
body: |
|
66
|
+
## Changes in v${{ steps.current_version.outputs.version }}
|
67
|
+
|
68
|
+
This release was automatically created from PR #${{ github.event.pull_request.number }}: ${{ github.event.pull_request.title }}
|
69
|
+
|
70
|
+
### Pull Request Details
|
71
|
+
${{ github.event.pull_request.body }}
|
72
|
+
|
73
|
+
### Artifacts
|
74
|
+
- **Python Wheel**: `flexfloat-${{ steps.current_version.outputs.version }}-py3-none-any.whl`
|
75
|
+
- **Source Distribution**: `flexfloat-${{ steps.current_version.outputs.version }}.tar.gz`
|
76
|
+
|
77
|
+
The package has been automatically published to [PyPI](https://pypi.org/project/flexfloat/${{ steps.current_version.outputs.version }}/).
|
78
|
+
draft: false
|
79
|
+
prerelease: false
|
80
|
+
files: |
|
81
|
+
./dist/flexfloat-${{ steps.current_version.outputs.version }}-py3-none-any.whl
|
82
|
+
./dist/flexfloat-${{ steps.current_version.outputs.version }}.tar.gz
|
83
|
+
|
84
|
+
- name: Publish to PyPI
|
85
|
+
uses: pypa/gh-action-pypi-publish@v1.12.4
|
86
|
+
with:
|
87
|
+
verbose: true
|
@@ -0,0 +1,121 @@
|
|
1
|
+
name: Version Bump
|
2
|
+
|
3
|
+
on:
|
4
|
+
pull_request_target:
|
5
|
+
types: [labeled, unlabeled]
|
6
|
+
|
7
|
+
jobs:
|
8
|
+
version-bump:
|
9
|
+
if: |
|
10
|
+
github.event.action == 'labeled' &&
|
11
|
+
github.event.label.name == 'release' &&
|
12
|
+
github.event.pull_request.merged == false
|
13
|
+
runs-on: ubuntu-latest
|
14
|
+
permissions:
|
15
|
+
contents: write
|
16
|
+
pull-requests: write
|
17
|
+
|
18
|
+
steps:
|
19
|
+
- name: Checkout PR branch
|
20
|
+
uses: actions/checkout@v4
|
21
|
+
with:
|
22
|
+
fetch-depth: 0
|
23
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
24
|
+
ref: ${{ github.event.pull_request.head.ref }}
|
25
|
+
|
26
|
+
- name: Set up Python
|
27
|
+
uses: actions/setup-python@v5
|
28
|
+
with:
|
29
|
+
python-version: "3.11"
|
30
|
+
|
31
|
+
- name: Install dependencies
|
32
|
+
run: |
|
33
|
+
python -m pip install --upgrade pip
|
34
|
+
pip install bump2version
|
35
|
+
|
36
|
+
- name: Configure Git
|
37
|
+
run: |
|
38
|
+
git config --local user.email "action@github.com"
|
39
|
+
git config --local user.name "GitHub Action"
|
40
|
+
|
41
|
+
- name: Determine version bump type
|
42
|
+
id: bump_type
|
43
|
+
run: |
|
44
|
+
BUMP_TYPE="patch"
|
45
|
+
LABELS="${{ join(github.event.pull_request.labels.*.name, ' ') }}"
|
46
|
+
if echo "$LABELS" | grep -q "major"; then
|
47
|
+
BUMP_TYPE="major"
|
48
|
+
elif echo "$LABELS" | grep -q "minor"; then
|
49
|
+
BUMP_TYPE="minor"
|
50
|
+
elif echo "$LABELS" | grep -q "patch"; then
|
51
|
+
BUMP_TYPE="patch"
|
52
|
+
fi
|
53
|
+
echo "bump_type=$BUMP_TYPE" >> $GITHUB_OUTPUT
|
54
|
+
echo "Version bump type: $BUMP_TYPE"
|
55
|
+
|
56
|
+
- name: Bump version
|
57
|
+
id: bump_version
|
58
|
+
run: |
|
59
|
+
bump2version ${{ steps.bump_type.outputs.bump_type }}
|
60
|
+
NEW_VERSION=$(grep -E '^version = ' pyproject.toml | cut -d'"' -f2)
|
61
|
+
echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT
|
62
|
+
echo "New version: $NEW_VERSION"
|
63
|
+
|
64
|
+
- name: Commit version bump to PR branch
|
65
|
+
run: |
|
66
|
+
git add pyproject.toml flexfloat/__init__.py .bumpversion.cfg
|
67
|
+
git commit -m "Bump version to ${{ steps.bump_version.outputs.new_version }} [skip ci]"
|
68
|
+
git push origin ${{ github.event.pull_request.head.ref }}
|
69
|
+
|
70
|
+
revert-version-bump:
|
71
|
+
if: |
|
72
|
+
github.event.action == 'unlabeled' &&
|
73
|
+
github.event.label.name == 'release' &&
|
74
|
+
github.event.pull_request.merged == false
|
75
|
+
runs-on: ubuntu-latest
|
76
|
+
permissions:
|
77
|
+
contents: write
|
78
|
+
pull-requests: write
|
79
|
+
|
80
|
+
steps:
|
81
|
+
- name: Checkout PR branch
|
82
|
+
uses: actions/checkout@v4
|
83
|
+
with:
|
84
|
+
fetch-depth: 0
|
85
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
86
|
+
ref: ${{ github.event.pull_request.head.ref }}
|
87
|
+
|
88
|
+
- name: Configure Git
|
89
|
+
run: |
|
90
|
+
git config --local user.email "action@github.com"
|
91
|
+
git config --local user.name "GitHub Action"
|
92
|
+
|
93
|
+
- name: Revert version bump commit
|
94
|
+
run: |
|
95
|
+
git fetch origin main
|
96
|
+
BASE_COMMIT=$(git merge-base HEAD origin/main)
|
97
|
+
VERSION_BUMP_COMMITS=()
|
98
|
+
for commit in $(git rev-list $BASE_COMMIT..HEAD); do
|
99
|
+
COMMIT_MSG=$(git log -1 --pretty=format:"%s" $commit)
|
100
|
+
if [[ $COMMIT_MSG == *"Bump version to"* ]] && [[ $COMMIT_MSG == *"[skip ci]"* ]]; then
|
101
|
+
VERSION_BUMP_COMMITS+=($commit)
|
102
|
+
fi
|
103
|
+
done
|
104
|
+
if [ ${#VERSION_BUMP_COMMITS[@]} -gt 0 ]; then
|
105
|
+
FIRST_VERSION_BUMP=${VERSION_BUMP_COMMITS[-1]}
|
106
|
+
RESET_TARGET=$(git rev-parse $FIRST_VERSION_BUMP^)
|
107
|
+
git reset --hard $RESET_TARGET
|
108
|
+
git push --force-with-lease origin ${{ github.event.pull_request.head.ref }}
|
109
|
+
echo "Version bump commits reverted"
|
110
|
+
fi
|
111
|
+
|
112
|
+
- name: Comment on PR
|
113
|
+
uses: actions/github-script@v7
|
114
|
+
with:
|
115
|
+
script: |
|
116
|
+
await github.rest.issues.createComment({
|
117
|
+
owner: context.repo.owner,
|
118
|
+
repo: context.repo.repo,
|
119
|
+
issue_number: context.issue.number,
|
120
|
+
body: '🚫 **Release Cancelled**: The `release` label was removed. Version bump commit has been reverted and this PR will not trigger a release when merged.'
|
121
|
+
});
|
@@ -19,15 +19,18 @@ jobs:
|
|
19
19
|
# Extract versions from different files
|
20
20
|
PYPROJECT_VERSION=$(grep -E '^version = ' pyproject.toml | cut -d'"' -f2)
|
21
21
|
INIT_VERSION=$(grep -E '^__version__ = ' flexfloat/__init__.py | cut -d'"' -f2)
|
22
|
+
BUMPVERSION_VERSION=$(grep -E '^current_version = ' .bumpversion.cfg | cut -d' ' -f3)
|
22
23
|
|
23
24
|
echo "pyproject.toml version: $PYPROJECT_VERSION"
|
24
25
|
echo "flexfloat/__init__.py version: $INIT_VERSION"
|
26
|
+
echo ".bumpversion.cfg current_version: $BUMPVERSION_VERSION"
|
25
27
|
|
26
28
|
# Check if versions match
|
27
|
-
if [ "$PYPROJECT_VERSION" != "$INIT_VERSION" ]; then
|
29
|
+
if [ "$PYPROJECT_VERSION" != "$INIT_VERSION" ] || [ "$PYPROJECT_VERSION" != "$BUMPVERSION_VERSION" ]; then
|
28
30
|
echo "[NO] Version mismatch detected!"
|
29
31
|
echo "pyproject.toml has version $PYPROJECT_VERSION"
|
30
32
|
echo "flexfloat/__init__.py has version $INIT_VERSION"
|
33
|
+
echo ".bumpversion.cfg has current_version $BUMPVERSION_VERSION"
|
31
34
|
echo "Please ensure all version references are synchronized."
|
32
35
|
exit 1
|
33
36
|
else
|
flexfloat-0.1.5/PKG-INFO
ADDED
@@ -0,0 +1,340 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: flexfloat
|
3
|
+
Version: 0.1.5
|
4
|
+
Summary: A library for arbitrary precision floating point arithmetic
|
5
|
+
Author: Ferran Sanchez Llado
|
6
|
+
License: MIT
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
8
|
+
Classifier: Intended Audience :: Developers
|
9
|
+
Classifier: Intended Audience :: Science/Research
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
11
|
+
Classifier: Operating System :: OS Independent
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
17
|
+
Requires-Python: >=3.11
|
18
|
+
Description-Content-Type: text/markdown
|
19
|
+
License-File: LICENSE
|
20
|
+
Provides-Extra: dev
|
21
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
22
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
23
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
24
|
+
Requires-Dist: isort>=5.0; extra == "dev"
|
25
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
26
|
+
Requires-Dist: pylint>=3.0; extra == "dev"
|
27
|
+
Requires-Dist: flake8>=6.0; extra == "dev"
|
28
|
+
Requires-Dist: bump2version>=1.0; extra == "dev"
|
29
|
+
Requires-Dist: build>=0.10; extra == "dev"
|
30
|
+
Requires-Dist: twine>=4.0; extra == "dev"
|
31
|
+
Requires-Dist: check-manifest>=0.49; extra == "dev"
|
32
|
+
Requires-Dist: PyYAML>=6.0; extra == "dev"
|
33
|
+
Dynamic: license-file
|
34
|
+
|
35
|
+
# FlexFloat
|
36
|
+
|
37
|
+
[](https://www.python.org/downloads/)
|
38
|
+
[](https://opensource.org/licenses/MIT)
|
39
|
+
[](https://badge.fury.io/py/flexfloat)
|
40
|
+
|
41
|
+
A high-precision Python library for arbitrary precision floating-point arithmetic with **growable exponents** and **fixed-size fractions**. FlexFloat extends IEEE 754 double-precision format to handle numbers beyond the standard range while maintaining computational efficiency and precision consistency.
|
42
|
+
|
43
|
+
## ✨ Key Features
|
44
|
+
|
45
|
+
- **🔢 Growable Exponents**: Dynamically expand exponent size to handle extremely large (>10^308) or small (<10^-308) numbers
|
46
|
+
- **🎯 Fixed-Size Fractions**: Maintain IEEE 754-compatible 52-bit fraction precision for consistent accuracy
|
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
|
49
|
+
- **🌟 Special Value Handling**: Complete support for NaN, ±infinity, and zero values
|
50
|
+
- **🛡️ Overflow Protection**: Automatic exponent growth prevents overflow/underflow errors
|
51
|
+
- **📊 IEEE 754 Baseline**: Fully compatible with standard double-precision format as the starting point
|
52
|
+
|
53
|
+
## 🚀 Quick Start
|
54
|
+
|
55
|
+
### Installation
|
56
|
+
|
57
|
+
```bash
|
58
|
+
pip install flexfloat
|
59
|
+
```
|
60
|
+
|
61
|
+
### Basic Usage
|
62
|
+
|
63
|
+
```python
|
64
|
+
from flexfloat import FlexFloat
|
65
|
+
|
66
|
+
# Create FlexFloat instances
|
67
|
+
a = FlexFloat.from_float(1.5)
|
68
|
+
b = FlexFloat.from_float(2.5)
|
69
|
+
|
70
|
+
# Perform arithmetic operations
|
71
|
+
result = a + b
|
72
|
+
print(result.to_float()) # 4.0
|
73
|
+
|
74
|
+
# Handle very large numbers that would overflow standard floats
|
75
|
+
large_a = FlexFloat.from_float(1e308)
|
76
|
+
large_b = FlexFloat.from_float(1e308)
|
77
|
+
large_result = large_a + large_b
|
78
|
+
|
79
|
+
# Result automatically grows exponent to handle the overflow
|
80
|
+
print(f"Exponent bits: {len(large_result.exponent)}") # > 11 (grown beyond IEEE 754)
|
81
|
+
print(f"Can represent: {large_result}") # No overflow!
|
82
|
+
```
|
83
|
+
|
84
|
+
### Advanced Examples
|
85
|
+
|
86
|
+
```python
|
87
|
+
from flexfloat import FlexFloat
|
88
|
+
|
89
|
+
# Mathematical operations
|
90
|
+
x = FlexFloat.from_float(2.0)
|
91
|
+
y = FlexFloat.from_float(3.0)
|
92
|
+
|
93
|
+
# Power operations
|
94
|
+
power_result = x ** y # 2^3 = 8
|
95
|
+
print(power_result.to_float()) # 8.0
|
96
|
+
|
97
|
+
# Exponential using Euler's number
|
98
|
+
e_result = FlexFloat.e ** x # e^2
|
99
|
+
print(f"e^2 ≈ {e_result.to_float()}")
|
100
|
+
|
101
|
+
# Working with extreme values
|
102
|
+
tiny = FlexFloat.from_float(1e-300)
|
103
|
+
huge = FlexFloat.from_float(1e300)
|
104
|
+
extreme_product = tiny * huge
|
105
|
+
print(f"Product: {extreme_product.to_float()}") # Still computable!
|
106
|
+
|
107
|
+
# Precision demonstration
|
108
|
+
precise_calc = FlexFloat.from_float(1.0) / FlexFloat.from_float(3.0)
|
109
|
+
print(f"1/3 with 52-bit precision: {precise_calc}")
|
110
|
+
```
|
111
|
+
|
112
|
+
## 🔧 BitArray Backends
|
113
|
+
|
114
|
+
FlexFloat supports multiple BitArray implementations for different performance characteristics:
|
115
|
+
|
116
|
+
```python
|
117
|
+
from flexfloat import (
|
118
|
+
FlexFloat,
|
119
|
+
set_default_implementation,
|
120
|
+
get_available_implementations
|
121
|
+
)
|
122
|
+
|
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)
|
129
|
+
|
130
|
+
# Use int64-based implementation (faster for small bit arrays)
|
131
|
+
set_default_implementation('int64')
|
132
|
+
flex_int64 = FlexFloat.from_float(42.0)
|
133
|
+
|
134
|
+
# Both produce the same results with different performance characteristics
|
135
|
+
```
|
136
|
+
|
137
|
+
### Implementation Comparison
|
138
|
+
|
139
|
+
| Implementation | Best For | Pros | Cons |
|
140
|
+
|---------------|----------|------|------|
|
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 |
|
143
|
+
|
144
|
+
## 📚 API Reference
|
145
|
+
|
146
|
+
### Core Operations
|
147
|
+
|
148
|
+
```python
|
149
|
+
# Construction
|
150
|
+
FlexFloat.from_float(value: float) -> FlexFloat
|
151
|
+
FlexFloat(sign: bool, exponent: BitArray, fraction: BitArray)
|
152
|
+
|
153
|
+
# Conversion
|
154
|
+
flexfloat.to_float() -> float
|
155
|
+
|
156
|
+
# Arithmetic
|
157
|
+
a + b, a - b, a * b, a / b, a ** b
|
158
|
+
abs(a), -a
|
159
|
+
|
160
|
+
# Mathematical functions
|
161
|
+
FlexFloat.e ** x # Exponential function
|
162
|
+
```
|
163
|
+
|
164
|
+
### Special Values
|
165
|
+
|
166
|
+
```python
|
167
|
+
from flexfloat import FlexFloat
|
168
|
+
|
169
|
+
# Create special values
|
170
|
+
nan_val = FlexFloat.nan()
|
171
|
+
inf_val = FlexFloat.infinity()
|
172
|
+
neg_inf = FlexFloat.negative_infinity()
|
173
|
+
zero_val = FlexFloat.zero()
|
174
|
+
|
175
|
+
# Check for special values
|
176
|
+
if result.is_nan():
|
177
|
+
print("Result is Not a Number")
|
178
|
+
if result.is_infinite():
|
179
|
+
print("Result is infinite")
|
180
|
+
```
|
181
|
+
|
182
|
+
## 🧪 Development & Testing
|
183
|
+
|
184
|
+
### Development Installation
|
185
|
+
|
186
|
+
```bash
|
187
|
+
git clone https://github.com/ferranSanchezLlado/flexfloat-py.git
|
188
|
+
cd flexfloat-py
|
189
|
+
pip install -e ".[dev]"
|
190
|
+
```
|
191
|
+
|
192
|
+
### Running Tests
|
193
|
+
|
194
|
+
```bash
|
195
|
+
# Run all tests
|
196
|
+
python -m pytest tests/
|
197
|
+
|
198
|
+
# Run with coverage
|
199
|
+
python -m pytest tests/ --cov=flexfloat --cov-report=html
|
200
|
+
|
201
|
+
# Run specific test categories
|
202
|
+
python -m pytest tests/test_arithmetic.py # Arithmetic operations
|
203
|
+
python -m pytest tests/test_conversions.py # Number conversions
|
204
|
+
python -m pytest tests/test_bitarray.py # BitArray implementations
|
205
|
+
```
|
206
|
+
|
207
|
+
### Code Quality
|
208
|
+
|
209
|
+
```bash
|
210
|
+
# Format code
|
211
|
+
black flexfloat/ tests/
|
212
|
+
|
213
|
+
# Sort imports
|
214
|
+
isort flexfloat/ tests/
|
215
|
+
|
216
|
+
# Type checking
|
217
|
+
mypy flexfloat/
|
218
|
+
|
219
|
+
# Linting
|
220
|
+
pylint flexfloat/
|
221
|
+
flake8 flexfloat/
|
222
|
+
```
|
223
|
+
|
224
|
+
## 🎯 Use Cases
|
225
|
+
|
226
|
+
### Scientific Computing
|
227
|
+
```python
|
228
|
+
# Handle calculations that would overflow standard floats
|
229
|
+
from flexfloat import FlexFloat
|
230
|
+
|
231
|
+
# Factorial of large numbers
|
232
|
+
def flex_factorial(n):
|
233
|
+
result = FlexFloat.from_float(1.0)
|
234
|
+
for i in range(1, n + 1):
|
235
|
+
result = result * FlexFloat.from_float(i)
|
236
|
+
return result
|
237
|
+
|
238
|
+
large_factorial = flex_factorial(1000) # No overflow!
|
239
|
+
```
|
240
|
+
|
241
|
+
### Financial Calculations
|
242
|
+
```python
|
243
|
+
# High-precision compound interest calculations
|
244
|
+
principal = FlexFloat.from_float(1000000.0)
|
245
|
+
rate = FlexFloat.from_float(1.05) # 5% annual return
|
246
|
+
years = FlexFloat.from_float(100)
|
247
|
+
|
248
|
+
# Calculate compound interest over very long periods
|
249
|
+
final_amount = principal * (rate ** years)
|
250
|
+
```
|
251
|
+
|
252
|
+
### Physics Simulations
|
253
|
+
```python
|
254
|
+
# Handle extreme values in physics calculations
|
255
|
+
c = FlexFloat.from_float(299792458) # Speed of light
|
256
|
+
mass = FlexFloat.from_float(1e-30) # Atomic mass
|
257
|
+
|
258
|
+
# E = mc² with extreme precision
|
259
|
+
energy = mass * c * c
|
260
|
+
```
|
261
|
+
|
262
|
+
## 🏗️ Architecture
|
263
|
+
|
264
|
+
FlexFloat is built with a modular architecture:
|
265
|
+
|
266
|
+
```
|
267
|
+
flexfloat/
|
268
|
+
├── core.py # Main FlexFloat class
|
269
|
+
├── types.py # Type definitions
|
270
|
+
├── bitarray/ # BitArray implementations
|
271
|
+
│ ├── bitarray.py # Abstract base class
|
272
|
+
│ ├── bitarray_list.py # List-based implementation
|
273
|
+
│ ├── bitarray_int64.py # Int64-based implementation
|
274
|
+
│ └── bitarray_mixins.py # Common functionality
|
275
|
+
└── __init__.py # Public API exports
|
276
|
+
```
|
277
|
+
|
278
|
+
### Design Principles
|
279
|
+
|
280
|
+
1. **IEEE 754 Compatibility**: Start with standard double-precision format
|
281
|
+
2. **Graceful Scaling**: Automatically expand exponent when needed
|
282
|
+
3. **Precision Preservation**: Keep fraction size fixed for consistent accuracy
|
283
|
+
4. **Performance Options**: Multiple backends for different use cases
|
284
|
+
5. **Pythonic Interface**: Natural syntax for mathematical operations
|
285
|
+
|
286
|
+
## 📊 Performance Considerations
|
287
|
+
|
288
|
+
### When to Use FlexFloat
|
289
|
+
|
290
|
+
✅ **Good for:**
|
291
|
+
- Calculations requiring numbers > 10^308 or < 10^-308
|
292
|
+
- Scientific computing with extreme values
|
293
|
+
- Financial calculations requiring high precision
|
294
|
+
- Preventing overflow/underflow in long calculations
|
295
|
+
|
296
|
+
❌ **Consider alternatives for:**
|
297
|
+
- Simple arithmetic with standard-range numbers
|
298
|
+
- Performance-critical tight loops
|
299
|
+
- Applications where standard `float` precision is sufficient
|
300
|
+
|
301
|
+
### Optimization Tips
|
302
|
+
|
303
|
+
```python
|
304
|
+
# Prefer int64 implementation for standard operations
|
305
|
+
set_default_implementation('int64')
|
306
|
+
|
307
|
+
# Batch operations when possible
|
308
|
+
values = [FlexFloat.from_float(x) for x in range(1000)]
|
309
|
+
sum_result = sum(values, FlexFloat.zero())
|
310
|
+
|
311
|
+
# Use appropriate precision for your use case
|
312
|
+
if value_in_standard_range:
|
313
|
+
result = float(flexfloat_result.to_float()) # Convert back if needed
|
314
|
+
```
|
315
|
+
|
316
|
+
## 📋 Roadmap
|
317
|
+
|
318
|
+
- [ ] Additional mathematical functions (sin, cos, tan, log, sqrt)
|
319
|
+
- [ ] Serialization support (JSON, pickle)
|
320
|
+
- [ ] Performance optimizations for large arrays
|
321
|
+
- [ ] Complex number support
|
322
|
+
- [ ] Decimal mode for exact decimal representation
|
323
|
+
|
324
|
+
|
325
|
+
## 📄 License
|
326
|
+
|
327
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
328
|
+
|
329
|
+
## 🙏 Acknowledgments
|
330
|
+
|
331
|
+
- IEEE 754 standard for floating-point arithmetic foundation
|
332
|
+
- Python community for inspiration and best practices
|
333
|
+
- Contributors and users who help improve the library
|
334
|
+
|
335
|
+
## 📞 Support
|
336
|
+
|
337
|
+
- 📚 **Documentation**: Full API documentation available in docstrings
|
338
|
+
- 🐛 **Issues**: Report bugs on [GitHub Issues](https://github.com/ferranSanchezLlado/flexfloat-py/issues)
|
339
|
+
- 💬 **Discussions**: Join conversations on [GitHub Discussions](https://github.com/ferranSanchezLlado/flexfloat-py/discussions)
|
340
|
+
- 📧 **Contact**: Reach out to the maintainer for questions
|