about | downloads | reference | class declarations | object declarations | exceptions | changelog |
Mbn (Multi-byte number) Library
Library for PHP and JS to do calculations with any precision and correct (half-up) rounding.
About
The main job of the library is to regain control of numbers.
Most of computer maths is based on float/double numbers which are fast and precise, but cause some problems in fixed-precision (e.g. financial) calculations.
It's also easy to get unexpected NaN and Infinity values. Results often need to be formatted in a particular way, which might or might not be available across languages.
With Mbn library:
Mbn is distributed under the MIT License, see Github page, get with
composer require mblajek/mbn
or
npm install mblajek-mbn
or
import Mbn from "https://esm.sh/mblajek-mbn"
Tests and benchmark
..
..
Downloads
Minified JS is created with Google Closure api
Minified PHP is created with custom text replacements, intended to be used in online PHP sandboxes like 3v4l.org
Generally code is optimized for speed and size; not for readability
mbn.js [ show | download ] (48.83 kB)
Library in JS
mbn.php [ show | download ] (46.93 kB)
Library in PHP
mbn.min.js [ show | download ] (14.49 kB)
Minified library in JS
mbn.min.php [ show | download ] (21.98 kB)
Minified library in PHP
mbn.d.ts [ show | download ] (2.18 kB)
TypeScript declaration file
Mbn.php [ show | download ] (41.91 kB)
Mbn class in PHP (with namespace, without MbnErr class)
MbnErr.php [ show | download ] (5.16 kB)
MbnErr class in PHP (with namespace)
Reference
JS and Mbn code equivalents.
In most cases Mbn code in PHP and JS is identical - a.f() in JS is $a->f() in PHP
operation JS (Number) Mbn JS (Number) Mbn return type
declaration a = b a = new Mbn(b) a = 0;
a = b;
a = new Mbn();
a.set(b);
Mbn
add a + b a.add(b) a += b a.add(b, true) Mbn
subtract a - b a.sub(b) a -= b a.sub(b, true) Mbn
multiply a * b a.mul(b) a *= b a.mul(b, true) Mbn
divide a / b a.div(b) a /= b a.div(b, true) Mbn
modulo a % b a.mod(b) a %= b a.mod(b, true) Mbn
result has same sign as the original number
minimum Math.min(a, b) a.min(b) a = Math.min(a, b) a.min(b, true) Mbn
maximum Math.max(a, b) a.max(b) a = Math.max(a, b) a.max(b, true) Mbn
power Math.pow(a, b) or a ** b a.pow(b) a = Math.pow(a, b) a.pow(b, true) Mbn
integer exponent only
factorial a.fact() a.fact(true) Mbn
round Math.round(a) a.round() a = Math.round(a) a.round(true) Mbn
floor Math.floor(a) a.floor() a = Math.floor(a) a.floor(true) Mbn
ceiling Math.ceil(a) a.ceil() a = Math.ceil(a) a.ceil(true) Mbn
integer part of value Math.trunc(a) a.intp() a = Math.trunc(a) a.intp(true) Mbn
absolute value Math.abs(a) a.abs() a = Math.abs(a) a.abs(true) Mbn
additive inverse -a a.inva() a = -a a.inva(true) Mbn
multiplicative inverse 1 / a a.invm() a = 1 / a a.invm(true) Mbn
square root Math.sqrt(a) a.sqrt() a = Math.sqrt(a) a.sqrt(true) Mbn
sign Math.sign(a) a.sgn() a = Math.sign(a) a.sgn(true) Mbn
negative → -1, positive → 1, 0 → 0
clone b = null
b = a
b = null
b = a.add(0)
b = 0;
b = a;
b = new Mbn()
b.set(a)
Mbn
operation 'b = a' when 'a' is an object only passes reference to existing instance of the object
a.add(0) is the easiest way to create new instance the same Mbn class with the same value
Mbn object has method 'set', so it can be modified
equals a === b a.eq(b) boolean
'b === a' when 'a' and 'b' are objects, only checks, if both vars are references to the same instance of object
equals
with max diff
Math.abs(a - b) <= 0.1 a.eq(b, 0.1) boolean
compare Math.sign(a - b) a.cmp(b) number [js]
int [php]
a < b → -1, a > b → 1, a === b → 0
comparing a < b
a <= b
a >= b
a > b
a.cmp(b) < 0
a.cmp(b) <= 0
a.cmp(b) >= 0
a.cmp(b) > 0
boolean
compare
with max diff
Math.abs(a - b) <= 0.1 a.cmp(b, 0.1) number [js]
int [php]
is integer Math.round(a) === a a.isInt() boolean
to number Number(a) a.toNumber() number [js]
int/float [php]
do not use Number(a) because it is equivalent to Number(a.toString()) which might apply rounding or fail, depending on the formatter
when precision is 0, toNumber in PHP returns int
to string a.toString() a.toString() [js,php]
$a->__toString() [php]
string
gets default string representation of Mbn, based on Mbn* class params
JS toString() and PHP __toString() are used by these languages by default while casting
(string)$a, ' '.$a [php], String(a), " "+a [js]
format a.format() string
gets string representation with changed Mbn* class params
params: boolean - enable thousands separator, default true
object - Mbn* params, truncation, formatting, precision, separator; missing parameters are taken from class
Class declarations
Each Mbn class has parameters defining its precision, default format and behavior
The library provides a single class named Mbn with default parameters (both in JS and PHP). This class can be extended.
Available parameters:
Class declarations in JS
Default Mbn class can be extended with Mbn.extend() method
Single precision as number, or object with Mbn* parameters can be passed.
hint: Mbn in JS is not exactly class, it's a class, a function and an object
Derived classes cannot be extended further
Class declarations in PHP
Default Mbn class can be extended with standard inheritance by overriding protected static fields
Mbn* fields which are not overridden have default values
Derived classes shouldn't be extended further
class Mbn0 extends Mbn {
protected static $MbnP = 0;
}
class Mbn4c extends Mbn {
protected static $MbnP = 4;
protected static $MbnS = ',';
}
class Mbn5t extends Mbn {
protected static $MbnP = 5;
protected static $MbnT = true;
}
Object declarations
There are several types of values that can be passed as the first constructor argument - the value
Second argument to constructor may be true / false or object [js] / array [php], which affects expression evaluation
as mentioned in class declarations and expression parser sections
In JS Mbn called as a function also returns new instance of Mbn (Mbn() instead of new Mbn())
Dealing with Mbn objects
Exceptions
All exceptions are instances of MbnErr class
JS: MbnErr has field "message", and method "toString" returns that message: ex.message, String(ex)
PHP: MbnErr extends Exception, message available with $ex->getMessage()
Moreover MbnErr has fields "errorKey" and "errorValues" which represent the particular erroneous situation.
Field errorValues contains string representations of values to the message, or is empty when there is no value to pass
Possible values of errorKey:
Changelog
Other methods
Array methods - split - split value into an array
A value can be split into an array of Mbn values that sum up to the original value
Array methods - reduce - map or reduce array
Array can be mapped or reduced with one of the Mbn methods
PHP: array can be associative
Other methods - calc