PHPackages                             jeremie-pasquis/rational-number - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. jeremie-pasquis/rational-number

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

jeremie-pasquis/rational-number
===============================

A type-safe PHP library for precise rational number arithmetic with automatic normalization and percentage operations

00[2 PRs](https://github.com/JeremiePRepo/RationalNumber/pulls)PHPCI passing

Since Apr 24Pushed 1w ago1 watchersCompare

[ Source](https://github.com/JeremiePRepo/RationalNumber)[ Packagist](https://packagist.org/packages/jeremie-pasquis/rational-number)[ RSS](/packages/jeremie-pasquis-rational-number/feed)WikiDiscussions main Synced today

READMEChangelogDependenciesVersions (14)Used By (0)

RationalNumber
==============

[](#rationalnumber)

[![PHP Version](https://camo.githubusercontent.com/c8d8dad6beb757a2b8acba331d16140813699543b88a37af0a81f20bd35f61de/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e332532422d626c7565)](https://camo.githubusercontent.com/c8d8dad6beb757a2b8acba331d16140813699543b88a37af0a81f20bd35f61de/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e332532422d626c7565)[![Tests](https://camo.githubusercontent.com/633610ef9c87bac398aedd90bb98351fd79b0a940d7dba8646989b078a90c268/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d32333125323070617373696e672d627269676874677265656e)](https://camo.githubusercontent.com/633610ef9c87bac398aedd90bb98351fd79b0a940d7dba8646989b078a90c268/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f74657374732d32333125323070617373696e672d627269676874677265656e)[![License](https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e)](https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e)[![CI](https://github.com/JeremiePRepo/RationalNumber/actions/workflows/ci.yml/badge.svg)](https://github.com/JeremiePRepo/RationalNumber/actions/workflows/ci.yml/badge.svg)[![PHPStan](https://camo.githubusercontent.com/14995ff65edea59395c224e37e4fc66f91c1e601c1a58311e3c6f38c4fe37feb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c2532306d61782d627269676874677265656e)](https://camo.githubusercontent.com/14995ff65edea59395c224e37e4fc66f91c1e601c1a58311e3c6f38c4fe37feb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c2532306d61782d627269676874677265656e)

A modern PHP library for precise rational number arithmetic. When floating-point math isn't accurate enough, `RationalNumber` guarantees exact calculations with fractions.

Why not just use floats?
------------------------

[](#why-not-just-use-floats)

Floating-point arithmetic introduces precision errors that can break calculations:

```
var_dump(0.1 + 0.2 === 0.3);  // false ❌
var_dump((0.1 + 0.2) - 0.3);  // 5.5511151231258E-17 ❌
```

`RationalNumber` guarantees exact arithmetic:

```
use RationalNumber\RationalNumber;

$result = RationalNumber::fromFloat(0.1)
    ->add(RationalNumber::fromFloat(0.2));

echo $result->getFloat();  // 0.3 ✅
```

Perfect for financial calculations, scientific computing, and anywhere precision matters.

**Not sure if RationalNumber is right for you?** See our [comparison with alternative libraries](docs/comparison.md) (brick/math, GMP, BCMath, native floats).

### Comparison: float vs RationalNumber

[](#comparison-float-vs-rationalnumber)

FeaturefloatRationalNumber`0.1 + 0.2 === 0.3`❌✅Exact fractions❌✅Speed✅⚠️Memory usage✅⚠️Features
--------

[](#features)

### Core

[](#core)

- Precise arithmetic (add, subtract, multiply, divide)
- Comparison methods (equals, greater than, less than, etc.)
- Immutable &amp; automatically normalized

### Advanced

[](#advanced)

- Power, square root, min, max
- Rounding (round, floor, ceil)
- Percentage support (increase, decrease, convert)
- Scientific notation support

### Infrastructure

[](#infrastructure)

- JSON serialization
- Collections for batch processing
- Overflow detection with GMP suggestions
- 175+ tests, 420+ assertions

Requirements
------------

[](#requirements)

- PHP 8.3 or later

**Performance note:** Rational numbers are slower than native floats due to normalization and overflow checks. Use them when precision matters more than raw speed.

Installation
------------

[](#installation)

```
composer require jeremie-pasquis/rational-number
```

Quick Start (5 minutes)
-----------------------

[](#quick-start-5-minutes)

### Creating Rational Numbers

[](#creating-rational-numbers)

```
use RationalNumber\RationalNumber;

// From numerator and denominator
$half = new RationalNumber(1, 2);      // 1/2

// From float
$twoAndHalf = RationalNumber::fromFloat(2.5);  // 5/2

// From string
$quarter = RationalNumber::fromString('0.25');  // 1/4
$pi = RationalNumber::fromString('22/7');       // 22/7

// Common values
$zero = RationalNumber::zero();
$one = RationalNumber::one();
```

### Basic Arithmetic

[](#basic-arithmetic)

```
$threeFourths = new RationalNumber(3, 4);  // 3/4
$oneHalf = new RationalNumber(1, 2);       // 1/2

// Addition
$result = $threeFourths->add($oneHalf);
echo $result->toString();  // "5/4"

// Subtraction, multiplication, division
$result = $threeFourths->subtract($oneHalf);   // "1/4"
$result = $threeFourths->multiply($oneHalf);   // "3/8"
$result = $threeFourths->divideBy($oneHalf);   // "3/2"

// Other operations
echo $threeFourths->reciprocal()->toString();  // "4/3"
echo $threeFourths->negate()->toString();      // "-3/4"
echo $threeFourths->abs()->toString();         // "3/4"
```

### Comparisons

[](#comparisons)

```
$half = new RationalNumber(1, 2);
$quarter = new RationalNumber(1, 4);

// Equality
if ($half->equals(new RationalNumber(2, 4))) {
    echo "Equal!";  // ✅
}

// Comparison methods
$half->isGreaterThan($quarter);         // true
$quarter->isLessThan($half);            // true
$half->isGreaterThanOrEqual($quarter);  // true
$half->compareTo($quarter);             // 1 (positive if greater)
```

### Working with Percentages

[](#working-with-percentages)

```
// Convert to/from percentage
$half = new RationalNumber(1, 2);
echo $half->toPercentage(2);  // "50.00%"

$number = RationalNumber::fromPercentage("75%");
echo $number->toString();  // "3/4"

// Calculations
$price = RationalNumber::fromFloat(100);
$withTax = $price->increaseByPercentage("20%");
echo $withTax->getFloat();  // 120

$discounted = $price->decreaseByPercentage("15%");
echo $discounted->getFloat();  // 85
```

Key Examples
------------

[](#key-examples)

### Financial Calculation

[](#financial-calculation)

```
use RationalNumber\RationalNumber;

// Calculate price with tax and discount
$originalPrice = RationalNumber::fromFloat(100.00);
$afterDiscount = $originalPrice->decreaseByPercentage("15%");  // $85.00
$finalPrice = $afterDiscount->increaseByPercentage("20%");     // $102.00

echo "Final Price: $" . $finalPrice->getFloat();  // $102.00
```

### Working with Collections

[](#working-with-collections)

```
use RationalNumber\RationalNumber;
use RationalNumber\Collection\RationalCollection;

$grades = new RationalCollection([
    RationalNumber::fromFloat(15.5),
    RationalNumber::fromFloat(17),
    RationalNumber::fromFloat(14.25),
    RationalNumber::fromFloat(16)
]);

echo $grades->average()->getFloat();  // 15.6875
echo $grades->max()->getFloat();      // 17.0

// Apply operations to all elements
$withBonus = $grades->map(fn($g) => $g->increaseByPercentage('5%'));
foreach ($withBonus as $grade) {
    echo $grade->toString() . "\n";
}
```

### JSON Serialization

[](#json-serialization)

```
use RationalNumber\RationalNumber;

$price = RationalNumber::fromFloat(99.99);
$json = json_encode($price);
// {"numerator":9999,"denominator":100,"float":99.99,"string":"9999/100"}

// Restore from JSON
$restored = RationalNumber::fromJson($json);
echo $restored->getFloat();  // 99.99
```

Documentation
-------------

[](#documentation)

For advanced usage, see:

- **[Advanced Operations](docs/advanced.md)** - Power, sqrt, rounding, overflow protection
- **[Collections](docs/collections.md)** - Batch processing with RationalCollection
- **[Serialization](docs/serialization.md)** - JSON, arrays, persistence
- **[Percentage Operations](docs/percentage.md)** - Complete percentage guide
- **[Performance Benchmarks](docs/benchmarks.md)** - Performance testing and optimization
- **[Library Comparison](docs/comparison.md)** - Compare with brick/math, GMP, BCMath, floats

### Generating API Documentation

[](#generating-api-documentation)

Generate HTML documentation from PHPDoc annotations:

```
composer docs
```

The generated documentation will be available at `docs/api/index.html`. For continuous documentation generation during development:

```
composer docs:watch
```

**Online Documentation:** [View API documentation](https://JeremiePRepo.github.io/RationalNumber/)

Design
------

[](#design)

This library is built around clean design principles:

- **Immutable value objects** - All operations return new instances, ensuring thread-safety and predictable behavior
- **Clear separation of concerns** - Distinct classes for arithmetic, factories, and percentage logic
- **Interface-driven design** - Contracts (`ArithmeticOperations`, `Comparable`, `NumericValue`) enable extensibility and testability

The design prioritizes precision, immutability, and developer experience while maintaining simplicity.

Testing
-------

[](#testing)

Run the test suite:

```
./vendor/bin/phpunit tests/
```

**Current metrics:** 175 tests, 420+ assertions

Coverage includes:

- All arithmetic and comparison operations
- Exception handling and edge cases
- Advanced math (pow, sqrt, min, max)
- Rounding operations
- Percentage calculations
- JSON serialization and collections
- PHP 8.3+ compatibility

Factory Pattern
---------------

[](#factory-pattern)

For flexible object creation:

```
use RationalNumber\Factory\RationalNumberFactory;

$factory = new RationalNumberFactory();

$number = $factory->create(3, 4);
$number = $factory->fromFloat(2.5);
$number = $factory->fromPercentage("50%");
$number = $factory->fromString("3/4");
```

License
-------

[](#license)

MIT License - Copyright (c) 2026 Jérémie Pasquis

See [LICENSE](LICENSE) file for details.

###  Health Score

24

—

LowBetter than 31% of packages

Maintenance64

Regular maintenance activity

Popularity0

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity21

Early-stage or recently created project

 Bus Factor1

Top contributor holds 90.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/013d07b84929fc60f18bfaf9083c0b71d833a4e8e3a1834054ed57a7b25ee19b?d=identicon)[JeremiePRepo](/maintainers/JeremiePRepo)

---

Top Contributors

[![JeremiePRepo](https://avatars.githubusercontent.com/u/11475095?v=4)](https://github.com/JeremiePRepo "JeremiePRepo (50 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (5 commits)")

### Embed Badge

![Health badge](/badges/jeremie-pasquis-rational-number/health.svg)

```
[![Health](https://phpackages.com/badges/jeremie-pasquis-rational-number/health.svg)](https://phpackages.com/packages/jeremie-pasquis-rational-number)
```

###  Alternatives

[tig/postnl-magento2

TIG Magento 2 PostNL extension

59570.5k5](/packages/tig-postnl-magento2)[arcanedev/laravel-notes

Provides the ability to add notes to your Eloquent models in Laravel.

4850.5k](/packages/arcanedev-laravel-notes)[kohkimakimoto/background-process

A minimum library to run background processes asynchronously.

351.4k](/packages/kohkimakimoto-background-process)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
