PHPackages                             jimeneztdavid/scaled-int - 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. jimeneztdavid/scaled-int

ActiveLibrary

jimeneztdavid/scaled-int
========================

A value object for scaled integers (e.g. money cents) with safe arithmetic and configurable rounding.

v1.1.0(3mo ago)14MITPHPPHP &gt;=8.1

Since Jan 26Pushed 3mo agoCompare

[ Source](https://github.com/jimeneztdavid/scaled-int)[ Packagist](https://packagist.org/packages/jimeneztdavid/scaled-int)[ RSS](/packages/jimeneztdavid-scaled-int/feed)WikiDiscussions main Synced 1mo ago

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

ScaledInt
=========

[](#scaledint)

Why this package exists
-----------------------

[](#why-this-package-exists)

Working with **money, prices, weights, percentages, or any decimal-based value** using floating-point numbers (`float`) is dangerous. Rounding errors, precision loss, and unexpected comparisons are common problems in real-world applications.

**ScaledInt** solves this by:

- Storing values internally as **integers only**
- Applying a fixed **scale (power of 10)** to represent decimals
- Providing **safe arithmetic**, comparisons, and rounding
- Avoiding floating-point math entirely

This makes it ideal for:

- Money and prices
- Taxes (IVA / VAT)
- Percentages and discounts
- Measurements (kg, grams, meters)
- Any domain where precision matters

---

Core concept
------------

[](#core-concept)

A `ScaledInt` stores:

- **minor** → integer value (scaled)
- **scale** → power of 10 (10, 100, 1000, etc.)

Example with scale `100`:

Human valueStored minor`10.25``1025``5.00``500``-3.50``-350`---

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

[](#installation)

```
composer require jimeneztdavid/scaled-int
```

---

Creating values
---------------

[](#creating-values)

### From a major (human) value

[](#from-a-major-human-value)

```
use Jimeneztdavid\ScaledInt\ScaledInt;

$price = ScaledInt::fromMajor('10.25'); // scale = 100 by default
```

### From a minor (integer) value

[](#from-a-minor-integer-value)

```
$price = ScaledInt::fromMinor(1025); // represents 10.25
```

### Using a custom scale

[](#using-a-custom-scale)

```
$weight = ScaledInt::fromMajor('1.234', 1000); // 3 decimals
```

⚠️ Scale **must be a power of 10** (`10`, `100`, `1000`, ...)

---

Reading values
--------------

[](#reading-values)

### Get minor value

[](#get-minor-value)

```
$price->minor(); // 1025
```

### Get scale

[](#get-scale)

```
$price->scale(); // 100
```

### Convert back to string

[](#convert-back-to-string)

```
$price->toMajorString(); // "10.25"
```

```
echo $price; // "10.25"
```

---

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

[](#comparisons)

All comparisons require **the same scale**.

```
$a = ScaledInt::fromMajor('10.00');
$b = ScaledInt::fromMajor('12.50');

$a->lessThan($b);     // true
$b->greaterThan($a); // true
$a->equalTo($b);     // false
```

compareTo()
-----------

[](#compareto)

Use `compareTo()` when you want a single method that tells you the ordering between two `ScaledInt` values.

- Returns **-1** if this value is **less than** the other
- Returns 0 if both values are **equal**
- Returns **1** if this value is **greater than** the other

> ⚠️ Both numbers must have the **same scale**, otherwise an `InvalidArgumentException` is thrown.

### Example

[](#example)

```
use Jimeneztdavid\ScaledInt\ScaledInt;

$a = ScaledInt::fromMajor('10.25'); // 10.25
$b = ScaledInt::fromMajor('10.30'); // 10.30
$c = ScaledInt::fromMajor('10.25'); // 10.25

$a->compareTo($b); // -1  (a < b)
$b->compareTo($a); //  1  (b > a)
$a->compareTo($c); //  0  (a == c)
```

---

Arithmetic operations
---------------------

[](#arithmetic-operations)

### Addition

[](#addition)

```
$total = $a->add($b);
```

### Subtraction

[](#subtraction)

```
$diff = $b->subtract($a);
```

### Multiply by integer

[](#multiply-by-integer)

```
$double = $price->multiplyByInt(2);
```

### Divide by integer (exact)

[](#divide-by-integer-exact)

```
$half = $price->divideByIntExact(2);
```

Throws if the division is not exact.

---

Division with rounding
----------------------

[](#division-with-rounding)

```
use Jimeneztdavid\ScaledInt\RoundingMode;

$result = $price->divideByInt(3, RoundingMode::HALF_UP);
```

Supported modes:

- `UP`
- `DOWN`
- `HALF_UP`
- `HALF_EVEN`

---

Percentages
-----------

[](#percentages)

```
$price = ScaledInt::fromMajor('100.00');

$iva = $price->percentOf(19, RoundingMode::HALF_UP); // 19.00
```

---

Common scenarios
----------------

[](#common-scenarios)

### Calculate IVA (VAT)

[](#calculate-iva-vat)

```
$price = ScaledInt::fromMajor('100.00');
$iva   = $price->percentOf(19, RoundingMode::HALF_UP);

$total = $price->add($iva); // 119.00
```

---

### Extract IVA from a final price

[](#extract-iva-from-a-final-price)

IVA included price formula:

```
base = total / (1 + IVA)

```

Example with 19% IVA:

```
$total = ScaledInt::fromMajor('119.00');

$base = $total
    ->multiplyByInt(100)
    ->divideByInt(119, RoundingMode::HALF_EVEN);

$iva = $total->subtract($base);
```

---

### Discounts

[](#discounts)

```
$price = ScaledInt::fromMajor('200.00');

$discount = $price->percentOf(15, RoundingMode::HALF_UP);
$final    = $price->subtract($discount);
```

---

### Measurements (non-money)

[](#measurements-non-money)

```
$weight = ScaledInt::fromMajor('2.750', 1000); // kg
$double = $weight->multiplyByInt(2);           // 5.500 kg
```

---

Why not floats?
---------------

[](#why-not-floats)

```
0.1 + 0.2 !== 0.3 // true 😬
```

```
ScaledInt::fromMajor('0.10')->add(
    ScaledInt::fromMajor('0.20')
)->toMajorString(); // "0.30" ✅
```

---

Design principles
-----------------

[](#design-principles)

- Immutable objects
- Integer-only math
- Explicit rounding
- Overflow-safe operations
- Scale consistency enforced

---

When to use ScaledInt
---------------------

[](#when-to-use-scaledint)

✅ Financial calculations
✅ Taxes and percentages
✅ Measurements
✅ Precise comparisons

❌ Scientific floating-point math
❌ Values requiring arbitrary precision decimals

---

Float vs ScaledInt
------------------

[](#float-vs-scaledint)

Aspect`float``ScaledInt`Precision❌ Imprecise (binary rounding errors)✅ Exact (integer math)Internal representationIEEE 754 binary floating pointInteger + fixed scale`0.1 + 0.2``0.30000000000000004` 😬`"0.30"` ✅Equality comparison❌ Unreliable✅ Safe and deterministicRounding control❌ Implicit and inconsistent✅ Explicit (UP, DOWN, HALF\_UP, HALF\_EVEN)Overflow detection❌ Silent✅ Explicit exceptionsCurrency safety❌ Dangerous✅ Designed for moneyPercentage calculations❌ Error-prone✅ DeterministicComparisons (`> < ==`)❌ Risky✅ Guaranteed correctnessDomain intent❌ Generic numeric✅ Explicit domain modelingProduction suitability⚠️ Needs extra care✅ Safe by defaultLicense
-------

[](#license)

MIT

###  Health Score

36

—

LowBetter than 81% of packages

Maintenance86

Actively maintained with recent releases

Popularity5

Limited adoption so far

Community2

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

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 ~0 days

Total

2

Last Release

103d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/26b7a75885ffcbf6e7e2b66ca5d37fa0b639ca36bb6654cf60b2c6255708928e?d=identicon)[jimeneztdavid](/maintainers/jimeneztdavid)

---

Tags

phpmoneyValue Objectdecimalroundingscaled-integer

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/jimeneztdavid-scaled-int/health.svg)

```
[![Health](https://phpackages.com/badges/jimeneztdavid-scaled-int/health.svg)](https://phpackages.com/packages/jimeneztdavid-scaled-int)
```

###  Alternatives

[moneyphp/money

PHP implementation of Fowler's Money pattern

4.8k82.5M421](/packages/moneyphp-money)[yandex-money/yandex-money-sdk-php

Yandex.Money API SDK for PHP

105167.4k2](/packages/yandex-money-yandex-money-sdk-php)[ulabox/money

Yet another PHP implementation of the Money value object using BCMath

77238.1k](/packages/ulabox-money)[adsmurai/currency

A small library to handle currencies and money values

4542.1k](/packages/adsmurai-currency)[comgate/sdk

Comgate PHP SDK

13327.8k](/packages/comgate-sdk)[kucharovic/money-bundle

This bundle provides integration for Money library in your Symfony project.

2253.7k](/packages/kucharovic-money-bundle)

PHPackages © 2026

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