PHPackages                             tresor-kasenda/laravel-numberable - 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. tresor-kasenda/laravel-numberable

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

tresor-kasenda/laravel-numberable
=================================

A fluent, expressive API for numeric operations in Laravel — like Stringable but for numbers.

v1.1.0(2mo ago)5231MITPHPPHP ^8.3CI failing

Since Feb 24Pushed 2mo agoCompare

[ Source](https://github.com/Tresor-Kasenda/laravel-numberable)[ Packagist](https://packagist.org/packages/tresor-kasenda/laravel-numberable)[ RSS](/packages/tresor-kasenda-laravel-numberable/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (1)Dependencies (8)Versions (3)Used By (0)

Laravel Numberable
==================

[](#laravel-numberable)

[![Latest Version on Packagist](https://camo.githubusercontent.com/8d38c9b8486381517d7bc37fcdc32df387b5348e7d618271333fecfb9c46acdd/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f747265736f722d6b6173656e64612f6c61726176656c2d6e756d62657261626c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/tresor-kasenda/laravel-numberable)[![Tests](https://camo.githubusercontent.com/19096e825f9bfdcf67cdf9d08288f31f73b13d49eeae4cf765a1da02bca5aadb/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f547265736f722d4b6173656e64612f6c61726176656c2d6e756d62657261626c652f74657374732e796d6c3f6c6162656c3d7465737473267374796c653d666c61742d737175617265)](https://github.com/Tresor-Kasenda/laravel-numberable/actions)[![License](https://camo.githubusercontent.com/7676a53684168217ce9f86a4d91f398b5fc2d29024ba2efb85b054af0aa603d8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f747265736f722d6b6173656e64612f6c61726176656c2d6e756d62657261626c652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/tresor-kasenda/laravel-numberable)

A fluent, expressive API for numeric operations in Laravel — **like `Stringable`, but for numbers**.

```
use TresorKasenda\Numberable\Numberable;

Numberable::make(1500)
    ->add(500)
    ->multiply(1.1)
    ->asCurrency('USD')
    ->withLocale('en_US')
    ->format(); // "$2,200.00"
```

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

[](#requirements)

- PHP 8.3+
- Laravel 10, 11, or 12
- `ext-intl` PHP extension
- Optional: `brick/math` for arbitrary-precision decimal math

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

[](#installation)

```
composer require tresor-kasenda/laravel-numberable
```

The package auto-registers its service provider via Laravel's package discovery.

For arbitrary-precision decimal operations (`addPrecise()`, `dividePrecise()`, etc.), install:

```
composer require brick/math
```

Quick Start
-----------

[](#quick-start)

There are several ways to create a `Numberable` instance:

```
use TresorKasenda\Numberable\Numberable;

// Using the static factory
$n = Numberable::make(42);
$n = Numberable::of(42); // alias

// Using the global helper
$n = number(42);

// Parsing strings (handles comma decimals)
$n = Numberable::parse('1.234,56', 'de_DE');
$n = Numberable::from('1.234,56', 'de_DE'); // alias

// Strict type parsing
$n = Numberable::parseInt('42');   // int
$n = Numberable::parseFloat('3.14'); // float
```

> The `number()` helper returns `null` when given `null`, making it safe for nullable values.

Arithmetic Operations
---------------------

[](#arithmetic-operations)

All operations are **immutable** — they return a new instance, leaving the original untouched.

```
$price = Numberable::make(100);

$price->add(50);         // 150
$price->subtract(20);    // 80
$price->multiply(2);     // 200
$price->divide(4);       // 25
$price->mod(3);          // 1
$price->pow(2);          // 10000
$price->abs();           // 100 (useful for negatives)
$price->round(2);        // rounds to 2 decimals
$price->floor();         // rounds down
$price->ceil();          // rounds up
$price->clamp(0, 100);   // keeps the value between 0 and 100
$price->trim();          // removes trailing decimal zeros (10.0 => 10)
```

### Chaining

[](#chaining)

Chain multiple operations fluently:

```
$result = number(100)
    ->add(50)
    ->multiply(2)
    ->subtract(10)
    ->divide(3)
    ->round(2)
    ->value(); // 96.67
```

> Division by zero throws a `\DivisionByZeroError`.

### Arbitrary Precision (Optional)

[](#arbitrary-precision-optional)

When `brick/math` is installed, you can perform decimal operations without float drift:

```
$result = Numberable::fromDecimal('0.1')
    ->addPrecise('0.2')
    ->multiplyPrecise('3')
    ->dividePrecise('7', scale: 8)
    ->roundPrecise(4)
    ->preciseValue(); // "0.1286"
```

Available precise methods:

- `Numberable::supportsArbitraryPrecision()`
- `Numberable::fromDecimal(int|float|string $value)`
- `->addPrecise()`, `->subtractPrecise()`, `->multiplyPrecise()`
- `->dividePrecise(int|float|string $value, int $scale = 14, string $roundingMode = 'HALF_UP')`
- `->modPrecise()`, `->roundPrecise()`
- `->comparePrecise()`, `->equalsPrecise()`, `->preciseValue()`

Formatting
----------

[](#formatting)

### Basic Formatting

[](#basic-formatting)

```
number(1234567)->format();                  // "1,234,567"
number(3.14159)->withPrecision(2)->format(); // "3.14"
number(1234.5)->withLocale('fr')->format();  // "1 234,5"
```

### Format Styles

[](#format-styles)

```
// Currency
number(1000)->asCurrency('EUR')->format();           // "€1,000.00"
number(1000)->withCurrency('USD')->asCurrency()->format(); // "$1,000.00"

// Percentage
number(75)->asPercentage()->format();   // "75%"

// Ordinal
number(1)->asOrdinal()->format();       // "1st"

// Spell out
number(5)->asSpell()->format();         // "five"

// File size
number(1048576)->asFileSize()->format(); // "1 MB"

// Abbreviation
number(1000000)->asAbbreviated()->format(); // "1M"
```

### Direct Style Formatting

[](#direct-style-formatting)

Use `formatAs()` to format with a specific style directly:

```
number(42)->formatAs('spell');       // "forty-two"
number(2)->formatAs('ordinal');      // "2nd"
number(1500)->formatAs('currency', ['currency' => 'GBP']); // "£1,500.00"
number(2048)->formatAs('fileSize');   // "2 KB"
```

**Available styles:** `currency`, `percentage`, `spell`, `ordinal`, `spellOrdinal`, `abbreviated` (alias: `summarized`), `fileSize` (alias: `humanReadable`)

### Locale Support

[](#locale-support)

Apply locale for any formatting via `withLocale()`:

```
number(1234.56)->withLocale('de_DE')->format(); // "1.234,56"
number(1000)->withLocale('fr_FR')->asCurrency('EUR')->format(); // "1 000,00 €"
```

Fluent Configuration
--------------------

[](#fluent-configuration)

Configure formatting options via immutable "with" methods:

```
number(1234.5678)
    ->withLocale('en_US')
    ->withPrecision(2)
    ->format(); // "1,234.57"

number(99.99)
    ->withCurrency('EUR')
    ->asCurrency()
    ->format(); // "€99.99"

number(3.14159)
    ->withMaxPrecision(3)
    ->format(); // "3.142"
```

Type Checks
-----------

[](#type-checks)

```
number(42)->isInt();       // true
number(3.14)->isInt();     // false
number(3.14)->isFloat();   // true
number(4)->isEven();       // true
number(5)->isOdd();        // true
number(12)->isMultipleOf(3); // true
number(17)->isPrime();     // true
number(5)->isPositive();   // true
number(-5)->isNegative();  // true
number(0)->isZero();       // true
```

Comparisons
-----------

[](#comparisons)

```
$n = number(10);

$n->equals(10);                     // true
$n->greaterThan(5);                 // true
$n->greaterThanOrEqualTo(10);       // true
$n->lessThan(20);                   // true
$n->lessThanOrEqualTo(10);          // true
$n->between(5, 10);                 // true (inclusive by default)
$n->between(5, 10, false);          // false if exactly on boundary
```

Conditional / Tap Helpers
-------------------------

[](#conditional--tap-helpers)

`Numberable` now includes Laravel's `Conditionable` and `Tappable` traits:

```
$result = number(100)
    ->when(app()->isProduction(), fn ($n) => $n->multiply(1.2))
    ->unless(auth()->check(), fn ($n) => $n->add(10))
    ->tap(fn ($n) => logger()->info('Computed total', ['value' => $n->value()]));
```

Value Accessors
---------------

[](#value-accessors)

```
number(3.9)->value();   // 3.9 (raw int|float)
number(3.9)->toInt();   // 3
number(42)->toFloat();  // 42.0
```

Pairs
-----

[](#pairs)

Generate range pairs — useful for building histograms, sliders, or pagination ranges:

```
number(0)->pairs(10, 3);
// [[0, 10], [10, 20], [20, 30]]

number(100)->pairs(25, 4);
// [[100, 125], [125, 150], [150, 175], [175, 200]]
```

Stringable
----------

[](#stringable)

`Numberable` implements `Stringable`, so it works anywhere a string is expected:

```
echo number(42);                    // "42"
echo number(3.14)->withPrecision(1); // "3.1"
echo number(75)->asPercentage();     // "75%"

$message = "Total: " . number(1000)->asCurrency('USD');
// "Total: $1,000.00"
```

Custom Formats
--------------

[](#custom-formats)

Register your own named format styles:

```
Numberable::registerFormat('compact', function (int|float $value, array $options = []) {
    $prefix = $options['prefix'] ?? '';
    return $prefix . number_format($value, 0, '.', 'k');
});

number(512)->formatAs('compact');                    // "512"
number(512)->formatAs('compact', ['prefix' => '#']); // "#512"
```

Custom formats take priority over built-in styles, allowing you to override defaults:

```
Numberable::registerFormat('currency', fn ($value) => "CUSTOM: $value");
number(100)->formatAs('currency'); // "CUSTOM: 100"
```

Clear all custom formats with:

```
Numberable::flushFormats();
```

Macros
------

[](#macros)

Extend `Numberable` with your own methods using Laravel's `Macroable` trait:

```
// Register a macro (e.g., in a service provider)
Numberable::macro('double', function () {
    return $this->multiply(2);
});

Numberable::macro('taxed', function (float $rate = 0.2) {
    return $this->multiply(1 + $rate);
});

// Use it
number(50)->double()->value();      // 100
number(100)->taxed(0.15)->value();  // 115.0

// Check if a macro exists
Numberable::hasMacro('double'); // true
```

Testing
-------

[](#testing)

```
composer test
```

Static Analysis
---------------

[](#static-analysis)

```
composer analyse
```

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance85

Actively maintained with recent releases

Popularity15

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% 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.

###  Release Activity

Cadence

Every ~4 days

Total

2

Last Release

79d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/2c1881faab5151123abdf9072ab481111c6150115b610dd0f6f34c0d3f66db43?d=identicon)[Scott-Tresor](/maintainers/Scott-Tresor)

---

Top Contributors

[![Tresor-Kasenda](https://avatars.githubusercontent.com/u/34010260?v=4)](https://github.com/Tresor-Kasenda "Tresor-Kasenda (22 commits)")

---

Tags

laravelmathfluentformattingnumber

###  Code Quality

TestsPest

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/tresor-kasenda-laravel-numberable/health.svg)

```
[![Health](https://phpackages.com/badges/tresor-kasenda-laravel-numberable/health.svg)](https://phpackages.com/packages/tresor-kasenda-laravel-numberable)
```

###  Alternatives

[barryvdh/laravel-ide-helper

Laravel IDE Helper, generates correct PHPDocs for all Facade classes, to improve auto-completion.

14.9k123.0M687](/packages/barryvdh-laravel-ide-helper)[hnhdigital-os/laravel-number-converter

Number to word, roman, ordinal converter

20163.3k2](/packages/hnhdigital-os-laravel-number-converter)[interaction-design-foundation/laravel-geoip

Support for multiple Geographical Location services.

17221.0k3](/packages/interaction-design-foundation-laravel-geoip)[nedwors/navigator

A Laravel package to ease defining navigation menus

433.1k](/packages/nedwors-navigator)[dcblogdev/laravel-junie

Install pre-configured guides for Jetbrains Junie

392.5k](/packages/dcblogdev-laravel-junie)

PHPackages © 2026

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