Skip to content

Commit de13a5e

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

File tree

1 file changed

+113
-43
lines changed

1 file changed

+113
-43
lines changed

README.md

Lines changed: 113 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,22 @@ 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 PHP extensions, falling back to a pure-PHP implementation if necessary.
22+
23+
Unless documented otherwise, all methods either return an exact result or throw an exception if the result is not exact.
24+
This behaviour can be customized by passing a `RoundingMode` enum to the relevant methods.
25+
1326
### Installation
1427

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

1730
```bash
1831
composer require brick/math
@@ -22,42 +35,40 @@ composer require brick/math
2235

2336
This library requires PHP 8.2 or later.
2437

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-
2738
Although the library can work seamlessly on any PHP installation, it is highly recommended that you install the
2839
[GMP](http://php.net/manual/en/book.gmp.php) or [BCMath](http://php.net/manual/en/book.bc.php) extension
2940
to speed up calculations. The fastest available calculator implementation will be automatically selected at runtime.
3041

31-
### Project status & release process
32-
33-
While this library is still under development, it is well tested and considered stable enough to use in production
34-
environments.
42+
### Release process
3543

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.
44+
This library follows [semantic versioning](https://semver.org/).
3845

39-
**When a breaking change is introduced, a new `0.x` version cycle is always started.**
46+
## Number classes
4047

41-
It is therefore safe to lock your project to a given release cycle, such as `^0.14`.
48+
The three number classes all extend the same `BigNumber` class:
4249

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.
50+
```
51+
Brick\Math\BigNumber
52+
├── Brick\Math\BigInteger
53+
├── Brick\Math\BigDecimal
54+
└── Brick\Math\BigRational
55+
```
4556

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

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

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.
65+
Comparison methods work across all number classes, you can for example compare a `BigInteger` to a `BigDecimal`, or a `BigDecimal` to a `BigRational`.
5566

56-
And [exceptions](#exceptions) in the `Brick\Math\Exception` namespace.
67+
`BigRational` numbers are always simplified to lowest terms, for example `2/6` is automatically simplified to `1/3`.
5768

58-
### Overview
69+
All classes work with an unlimited number of digits (or, to be exact, limited at ~`PHP_INT_MAX` digits), effectively only limited by available memory and CPU time.
5970

60-
#### Instantiation
71+
## Instantiation
6172

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

@@ -89,7 +100,7 @@ BigDecimal::of('1/8'); // 0.125
89100
BigDecimal::of('1/3'); // RoundingNecessaryException
90101

91102
BigRational::of('1.1'); // 11/10
92-
BigRational::of('1.15'); // 23/20 (reduced to lowest terms)
103+
BigRational::of('1.15'); // 23/20
93104
```
94105

95106
> [!NOTE]
@@ -107,7 +118,7 @@ BigRational::of('1.15'); // 23/20 (reduced to lowest terms)
107118
> BigDecimal::of((string) $float);
108119
> ```
109120
110-
#### Immutability & chaining
121+
## Immutability & chaining
111122
112123
The `BigInteger`, `BigDecimal` and `BigRational` classes are immutable: their value never changes,
113124
so that they can be safely passed around. All methods that return a `BigInteger`, `BigDecimal` or `BigRational`
@@ -126,7 +137,7 @@ The methods can be chained for better readability:
126137
echo BigInteger::of(10)->plus(5)->multipliedBy(3); // 45
127138
```
128139

129-
#### Parameter types
140+
### Parameter types
130141

131142
All methods that accept a number: `plus()`, `minus()`, `multipliedBy()`, etc. accept the same types as `of()`.
132143
For example, given the following number:
@@ -151,9 +162,9 @@ echo BigInteger::of(2)->multipliedBy(BigDecimal::of('2.5')); // RoundingNecessar
151162
echo BigDecimal::of(2.5)->multipliedBy(BigInteger::of(2)); // 5.0
152163
```
153164

154-
#### Division & rounding
165+
## Division & rounding
155166

156-
##### BigInteger
167+
### BigInteger
157168

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

186-
##### BigDecimal
197+
### BigDecimal
187198

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

207-
##### BigRational
218+
### BigRational
208219

209220
The result of the division of a `BigRational` can always be represented exactly:
210221

@@ -213,21 +224,80 @@ echo BigRational::of('13/99')->dividedBy('7'); // 13/693
213224
echo BigRational::of('13/99')->dividedBy('9/8'); // 104/891
214225
```
215226

216-
#### Bitwise operations
217227

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

220-
- `and()`
221-
- `or()`
222-
- `xor()`
223-
- `not()`
292+
[//]: # ()
293+
[//]: # (and bit shifting:)
224294

225-
and bit shifting:
295+
[//]: # ()
296+
[//]: # (- `shiftedLeft&#40;&#41;`)
226297

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

230-
#### Exceptions
300+
## Exceptions
231301

232302
All exceptions thrown by this library implement the `MathException` interface.
233303
This means that you can safely catch all exceptions thrown by this library using a single catch clause:
@@ -243,7 +313,7 @@ try {
243313
}
244314
```
245315

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

248318
- `DivisionByZeroException`
249319
- `IntegerOverflowException`
@@ -253,7 +323,7 @@ If you need more granular control over the exceptions thrown, you can catch the
253323
- `NumberFormatException`
254324
- `RoundingNecessaryException`
255325

256-
#### Serialization
326+
## Serialization
257327

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

0 commit comments

Comments
 (0)