Skip to content

Commit bae71b7

Browse files
committed
Update README
[skip CI]
1 parent a4dee0c commit bae71b7

File tree

1 file changed

+130
-43
lines changed

1 file changed

+130
-43
lines changed

README.md

Lines changed: 130 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## Brick\Math
1+
# Brick\Math
22

33
<img src="https://raw.githubusercontent.com/brick/brick/master/logo.png" alt="" align="left" height="64">
44

@@ -10,9 +10,19 @@ A PHP library to work with arbitrary precision numbers.
1010
[![Total Downloads](https://poser.pugx.org/brick/math/downloads)](https://packagist.org/packages/brick/math)
1111
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](http://opensource.org/licenses/MIT)
1212

13+
## Introduction
14+
15+
This library provides immutable classes to work with arbitrary precision numbers:
16+
17+
- `BigInteger` — integer number, e.g. `123`
18+
- `BigDecimal` — decimal number, e.g. `1.23`
19+
- `BigRational` — fraction, e.g. `2/3`
20+
21+
It works with or without the GMP or BCMath extensions, falling back to a pure-PHP implementation if necessary.
22+
1323
### Installation
1424

15-
This library is installable via [Composer](https://getcomposer.org/):
25+
This library is installable via [composer](https://getcomposer.org/):
1626

1727
```bash
1828
composer require brick/math
@@ -22,42 +32,39 @@ composer require brick/math
2232

2333
This library requires PHP 8.2 or later.
2434

25-
For PHP 8.1 compatibility, you can use version `0.13`. For PHP 8.0, you can use version `0.11`. For PHP 7.4, you can use version `0.10`. For PHP 7.1, 7.2 & 7.3, you can use version `0.9`. Note that [PHP versions < 8.1 are EOL](http://php.net/supported-versions.php) and not supported anymore. If you're still using one of these PHP versions, you should consider upgrading as soon as possible.
26-
2735
Although the library can work seamlessly on any PHP installation, it is highly recommended that you install the
2836
[GMP](http://php.net/manual/en/book.gmp.php) or [BCMath](http://php.net/manual/en/book.bc.php) extension
2937
to speed up calculations. The fastest available calculator implementation will be automatically selected at runtime.
3038

31-
### Project status & release process
39+
### Release process
3240

33-
While this library is still under development, it is well tested and considered stable enough to use in production
34-
environments.
41+
This library follows [semantic versioning](https://semver.org/).
3542

36-
The current releases are numbered `0.x.y`. When a non-breaking change is introduced (adding new methods, optimizing
37-
existing code, etc.), `y` is incremented.
43+
## Number classes
3844

39-
**When a breaking change is introduced, a new `0.x` version cycle is always started.**
45+
The three number classes all extend the same `BigNumber` class:
4046

41-
It is therefore safe to lock your project to a given release cycle, such as `^0.14`.
42-
43-
If you need to upgrade to a newer release cycle, check the [release history](https://github.com/brick/math/releases)
44-
for a list of changes introduced by each further `0.x.0` version.
47+
```
48+
Brick\Math\BigNumber
49+
├── Brick\Math\BigInteger
50+
├── Brick\Math\BigDecimal
51+
└── Brick\Math\BigRational
52+
```
4553

46-
### Package contents
54+
`BigNumber` is an abstract class that defines the common behaviour of all number classes:
4755

48-
This library provides the following public classes in the `Brick\Math` namespace:
56+
- `of()` — to obtain an instance
57+
- sign methods: `isZero()`, `isPositive()`, etc.
58+
- comparison methods: `isEqualTo()`, `isGreaterThan()`, etc.
59+
- `min()`, `max()`, `sum()`, `toString()` etc.
4960

50-
- [BigNumber](https://github.com/brick/math/blob/0.14.7/src/BigNumber.php): base class for `BigInteger`, `BigDecimal` and `BigRational`
51-
- [BigInteger](https://github.com/brick/math/blob/0.14.7/src/BigInteger.php): represents an arbitrary-precision integer number.
52-
- [BigDecimal](https://github.com/brick/math/blob/0.14.7/src/BigDecimal.php): represents an arbitrary-precision decimal number.
53-
- [BigRational](https://github.com/brick/math/blob/0.14.7/src/BigRational.php): represents an arbitrary-precision rational number (fraction), always reduced to lowest terms.
54-
- [RoundingMode](https://github.com/brick/math/blob/0.14.7/src/RoundingMode.php): enum representing all available rounding modes.
61+
Comparison methods work across all number classes, you can for example compare a `BigInteger` to a `BigDecimal`, or a `BigDecimal` to a `BigRational`.
5562

56-
And [exceptions](#exceptions) in the `Brick\Math\Exception` namespace.
63+
All classes work with a virtually unlimited number of digits, and are limited only by available memory and CPU time.
5764

58-
### Overview
65+
`BigRational` numbers are always simplified to lowest terms, for example `2/6` is automatically simplified to `1/3`.
5966

60-
#### Instantiation
67+
## Instantiation
6168

6269
The constructors of the classes are not public, you must use a factory method to obtain an instance.
6370

@@ -89,7 +96,7 @@ BigDecimal::of('1/8'); // 0.125
8996
BigDecimal::of('1/3'); // RoundingNecessaryException
9097

9198
BigRational::of('1.1'); // 11/10
92-
BigRational::of('1.15'); // 23/20 (reduced to lowest terms)
99+
BigRational::of('1.15'); // 23/20
93100
```
94101

95102
> [!NOTE]
@@ -107,7 +114,7 @@ BigRational::of('1.15'); // 23/20 (reduced to lowest terms)
107114
> BigDecimal::of((string) $float);
108115
> ```
109116
110-
#### Immutability & chaining
117+
## Immutability & chaining
111118
112119
The `BigInteger`, `BigDecimal` and `BigRational` classes are immutable: their value never changes,
113120
so that they can be safely passed around. All methods that return a `BigInteger`, `BigDecimal` or `BigRational`
@@ -126,7 +133,7 @@ The methods can be chained for better readability:
126133
echo BigInteger::of(10)->plus(5)->multipliedBy(3); // 45
127134
```
128135

129-
#### Parameter types
136+
## Parameter types
130137

131138
All methods that accept a number: `plus()`, `minus()`, `multipliedBy()`, etc. accept the same types as `of()`.
132139
For example, given the following number:
@@ -151,9 +158,29 @@ echo BigInteger::of(2)->multipliedBy(BigDecimal::of('2.5')); // RoundingNecessar
151158
echo BigDecimal::of(2.5)->multipliedBy(BigInteger::of(2)); // 5.0
152159
```
153160

154-
#### Division & rounding
161+
## Rounding
162+
163+
Unless documented otherwise, all methods either return an exact result or throw an exception if the result is not exact.
164+
This is typically configurable through an optional `RoundingMode` parameter:
165+
166+
| Rounding mode | Description |
167+
|-----------------------------|---------------------------------------------------------------|
168+
| `RoundingMode::Unnecessary` | Requires an exact result; throws if rounding would be needed. |
169+
| `RoundingMode::Up` | Rounds away from zero. |
170+
| `RoundingMode::Down` | Rounds toward zero. |
171+
| `RoundingMode::Ceiling` | Rounds toward positive infinity. |
172+
| `RoundingMode::Floor` | Rounds toward negative infinity. |
173+
| `RoundingMode::HalfUp` | Rounds to nearest; ties away from zero. |
174+
| `RoundingMode::HalfDown` | Rounds to nearest; ties toward zero. |
175+
| `RoundingMode::HalfCeiling` | Rounds to nearest; ties toward positive infinity. |
176+
| `RoundingMode::HalfFloor` | Rounds to nearest; ties toward negative infinity. |
177+
| `RoundingMode::HalfEven` | Rounds to nearest; ties to the even neighbor. |
155178

156-
##### BigInteger
179+
See the next section for examples of `RoundingMode` in action.
180+
181+
## Division & rounding
182+
183+
### BigInteger
157184

158185
By default, dividing a `BigInteger` returns the exact result of the division, or throws an exception if the remainder
159186
of the division is not zero:
@@ -183,7 +210,7 @@ You can even get both at the same time:
183210
[$quotient, $remainder] = BigInteger::of(1000)->quotientAndRemainder(3);
184211
```
185212

186-
##### BigDecimal
213+
### BigDecimal
187214

188215
Dividing a `BigDecimal` always requires a scale to be specified. If the exact result of the division does not fit in
189216
the given scale, a [rounding mode](https://github.com/brick/math/blob/0.14.7/src/RoundingMode.php) must be provided.
@@ -204,7 +231,7 @@ echo BigDecimal::of(1)->dividedByExact(256); // 0.00390625
204231
echo BigDecimal::of(1)->dividedByExact(11); // RoundingNecessaryException
205232
```
206233

207-
##### BigRational
234+
### BigRational
208235

209236
The result of the division of a `BigRational` can always be represented exactly:
210237

@@ -213,21 +240,80 @@ echo BigRational::of('13/99')->dividedBy('7'); // 13/693
213240
echo BigRational::of('13/99')->dividedBy('9/8'); // 104/891
214241
```
215242

216-
#### Bitwise operations
217243

218-
`BigInteger` supports bitwise operations:
244+
## Conversion to string
245+
246+
All number classes can be converted to string using either the `toString()` method, or the `(string)` cast. For example, the following lines are equivalent:
247+
248+
```php
249+
echo BigInteger::of(123)->toString();
250+
echo (string) BigInteger::of(123);
251+
```
252+
253+
Different number classes produce different outputs, but will all fold to plain digit strings if they represent a whole number:
254+
255+
```php
256+
echo BigInteger::of(-123)->toString(); // -123
257+
258+
echo BigDecimal::of('1.0')->toString(); // 1.0
259+
echo BigDecimal::of('1')->toString(); // 1
260+
261+
echo BigRational::of('2/3')->toString(); // 2/3
262+
echo BigRational::of('1/1')->toString(); // 1
263+
```
264+
265+
All string outputs are parseable by the `of()` factory method, i.e. this is guaranteed to work:
266+
267+
```php
268+
BigNumber::of($bigNumber->toString());
269+
```
270+
271+
> [!IMPORTANT]
272+
> Because `BigDecimal::toString()` and `BigRational::toString()` can return whole numbers, some numbers can be returned
273+
> as `BigInteger` when parsed using `BigNumber::of()`. If you want to retain the original type when reparsing numbers,
274+
> be sure to use `BigDecimal::of()` or `BigRational::of()`.
275+
276+
### Converting BigRational to decimal string
277+
278+
In addition to the standard rational representation such as `2/3`, rational numbers can be represented as decimal numbers
279+
with a potentially repeating suite of digits. You can use `toRepeatingDecimalString()` to get this representation:
280+
281+
```php
282+
BigRational::of('1/2')->toRepeatingDecimalString(); // 0.5
283+
BigRational::of('2/3')->toRepeatingDecimalString(); // 0.(6)
284+
BigRational::of('171/70')->toRepeatingDecimalString(); // 2.4(428571)
285+
```
286+
287+
The part in parentheses is the repeating period, if any.
288+
289+
> [!WARNING]
290+
> `BigRational::toRepeatingDecimalString()` is unbounded.
291+
> The repeating period can be as large as `denominator - 1`, so large denominators can require a lot of memory and CPU time.
292+
> Example: `BigRational::of('1/100019')->toRepeatingDecimalString()` has a repeating period of 100,018 digits.
293+
294+
[//]: # (## Bitwise operations)
295+
296+
[//]: # ()
297+
[//]: # (`BigInteger` supports bitwise operations:)
298+
299+
[//]: # ()
300+
[//]: # (- `and&#40;&#41;`)
301+
302+
[//]: # (- `or&#40;&#41;`)
303+
304+
[//]: # (- `xor&#40;&#41;`)
305+
306+
[//]: # (- `not&#40;&#41;`)
219307

220-
- `and()`
221-
- `or()`
222-
- `xor()`
223-
- `not()`
308+
[//]: # ()
309+
[//]: # (and bit shifting:)
224310

225-
and bit shifting:
311+
[//]: # ()
312+
[//]: # (- `shiftedLeft&#40;&#41;`)
226313

227-
- `shiftedLeft()`
228-
- `shiftedRight()`
314+
[//]: # (- `shiftedRight&#40;&#41;`)
229315

230-
#### Exceptions
316+
## Exceptions
231317

232318
All exceptions thrown by this library implement the `MathException` interface.
233319
This means that you can safely catch all exceptions thrown by this library using a single catch clause:
@@ -243,17 +329,18 @@ try {
243329
}
244330
```
245331

246-
If you need more granular control over the exceptions thrown, you can catch the specific exception classes:
332+
If you need more granular control over the exceptions thrown, you can catch the specific exception classes documented in each method:
247333

248334
- `DivisionByZeroException`
249335
- `IntegerOverflowException`
250336
- `InvalidArgumentException`
251337
- `NegativeNumberException`
252338
- `NoInverseException`
253339
- `NumberFormatException`
340+
- `RandomSourceException`
254341
- `RoundingNecessaryException`
255342

256-
#### Serialization
343+
## Serialization
257344

258345
`BigInteger`, `BigDecimal` and `BigRational` can be safely serialized on a machine and unserialized on another,
259346
even if these machines do not share the same set of PHP extensions.

0 commit comments

Comments
 (0)