The fNumber class is a value object to represent large integers and arbitrary precision decimal values. The fNumber class is essential when dealing with calculations that must be precise, such as monetary value (consequently the fMoney class is built on top of fNumber). It supplies the same math functionality that is built into PHP, minus the trigonometric operations.

An fNumber object requires just a single parameter for the constructor, the value to represent. It can be a string, an object with a `__toString()`

method, or an integer. If the value being represented is too large to store in an integer, the integer value should be enter via a string to prevent data loss. Also, float values should never be used since they have an inherent loss of precision that this class is designed to overcome.

```
$five = new fNumber(5);
$four_point_two = new fNumber('4.2');
$zero_point_one = new fNumber('0.1');
```

There is a second optional parameter to the constructor that allows specifying the precision of the number. If no precision is specified, the precision of the value is used.

```
// Represents 1.000
$one = new fNumber(1, 3);
```

Basic arithmetic is performed using the method `add()`

, `sub()`

, `mul()`

and `div()`

. Since the fNumber class is a value object, all operations return a new fNumber object instead of modifying the existing one. Also, all methods accept any valid number representation including strings, fNumber objects and integers.

The returned fNumber object will have the same precision as the object being called unless the optional parameter `$scale`

is included.

Addition is performed by calling the method `add()`

and providing an `$addend`

.

```
// Addition using different addend number forms
$six = $five->add(1);
$six = $five->add($one);
$eight_point_four = $four_point_two->add('4.2');
// Without scale the 0.1 is lost
$five = $five->add('0.1');
// By specifying a scale of 1 we retain the 0.1
$five_point_one = $five->add('0.1', 1);
```

Subtraction is performed by calling the method `sub()`

and providing a `$subtrahend`

.

```
// Basic subtraction
$two = $five->sub(3);
// Since $five has a scale of zero, the result is still five
$five = $five->sub('0.3');
// All arithmetic methods support positive and negative numbers
$five_point_three = $five->sub('-0.3', 1);
```

Multiplication is performed by calling the method `mul()`

and providing a `$multiplicand`

.

```
// Simple multiplication
$ten = $five->mul(2);
// A comparison of multiplication with 0 and 1 scale
$twelve = $five->mul('2.5');
$twelve_point_five = $five->mul('2.5', 1);
```

Division is performed by calling the method `div()`

and providing a `$divisor`

.

```
// Basic division
$two = $five->div(2);
// Division with a specific scale
$two_point_five = $five->div(2, 1);
```

The remainder of integer division can be calculated by the method `mod()`

and the remainder of fractional division can be calculated by the method `fmod()`

.

The `mod()`

method will convert the current number to an integer and then divide it by the single parameter, `$divisor`

, that is passed to the method. The `$divisor`

is also converted to an integer before the calculation is performed.

```
// Simple integer division
$one = $three->mod('2');
// The number and divisor are both converted to integers first
$one = $three_point_two->mod('2.1');
```

The `fmod()`

method allows dividing a fractional number by another fractional number, returning the remainder. The first parameter is the `$divisor`

to use, while a second optional parameter, `$scale`

, allows specifying the scale of the remainder that is being returned.

```
$zero_point_three = $four_point_seven->fmod('1.1');
$one_point_four_zero = $four_point_four->fmod('1.5', 2);
```

The fNumber class provides functionality to calculate both square roots and integer powers via the `sqrt()`

and `pow()`

methods.

The `sqrt()`

method accepts a single optional parameter, the `$scale`

of the result.

```
$three = $nine->sqrt();
$three_point_eight = $fifteen->sqrt(1);
```

The `pow()`

method accepts two parameters, the required `$exponent`

to raise the number to, and the optional `$scale`

for the resulting number.

```
$twenty_five = $five->pow(2);
$nine_point_two_six = $two_point_one->pow(3, 2);
```

Under certain situations, especially when dealing with cryptography, it is necessary to raise integers to large powers and then calculate the remainder of the division of that product by another integer. Normal calculation by raising the original number to a large power and then dividing to find the remainder often takes far too much computation. There are, however, some mathematical shortcuts to make such calculations significantly faster.

The `powmod()`

method allows calculating the remainder of the original number raised to an `$exponent`

and then divided by the `$modulus`

.

`$four_fourty_five = $four->powmod('13', '497');`

The fNumber class include comparison methods for testing equality - `eq()`

, less than - `lt()`

, less than or equal - `lte()`

, greater than - `gt()`

and greater than or equal - `gte()`

. Each method accepts two parameters, the `$number`

to compare to and an optional `$scale`

to use for comparison.

The `$number`

to compare to may be any valid fNumber object, string or integer. The `$scale`

parameter sets how many digits after the decimal point to use during comparison. If no scale is specified, the highest scale of the two numbers will be used.

```
$true = $five->eq(5);
$false = $five->eq('5.1');
$true = $five->eq('5.1', 0);
$true = $five->lt($six);
$true = $five->lte('5.00', 4);
$false = $five->gt($six, 0);
$false = $five->gte('5.1', 1);
```

There are two options to format fNumber objects, either `__toString()`

or `format()`

. The `format()`

method will include thousands separators in the returned value, while `__toString()`

will not. The inherent scale of the number will be used when displaying the value. To change the scale, use the `trunc()`

or `round()`

method first.

```
echo $one_thousand_two_hundred->format() . "\n";
echo $one_thousand_two_hundred->__toString() . "\n";
echo $negative_five_point_two->format() . "\n";
echo $negative_five_point_two->__toString() . "\n";
echo $negative_five_point_two->trunc()->__toString();
```

would output the following

```
1,200
1200
-5.2
-5.2
-5
```

If the parameter `$remove_zero_fraction`

is set to `TRUE`

and the value has a fraction that is just zeros, the resulting output will not contain a decimal point or a fraction.

```
// This will print: 5
$five = new fNumber('5.0');
echo $five->format(TRUE);
$two_fifty_three = new fNumber('2.53');
// This will print: 2.53
echo $two_fifty_three->format(TRUE);
```

The precision of an fNumber can be modified by using the `ceil()`

, `floor()`

, `round()`

and `trunc()`

methods.

The `ceil()`

method performs a ceiling operation, rounding up to the next highest integer.

`$six = $five_point_two->ceil();`

The `floor()`

method preforms a floor operation, rounding down to the next lowest integer.

`$negative_six = $negative_five_point_two->floor();`

The `trunc()`

method changes the scale of the number to 0 without performing any rounding.

`$five = $five_point_two->trunc();`

The `round()`

method allows rounding a number to a specified number of decimal places, using the `$scale`

parameter. It is even possible to round left of the decimal point using negative scales. Rounding is done using the common method, that is when the digit one place beyond the `$scale`

is 5 or greater the `$scale`

digit is increased vy 1, otherwise the digit is left the same.

```
// Rounding positive numbers
$five = $five_point_two->round();
$six = $five_point_five->round();
// Rounding negative numbers
$negative_two = $negative_one_point_six->round();
$negative_one = $negative_one_point_one->round();
// Rounding to a specific scale
$one_point_three = $one_point_three_three->round(1);
$ten = $thirteen->round(-1);
```

The fNumber class can calculate the absolute value of a number via the `abs()`

method, the negated value via the `neg()`

method and can return the sign of a number via the `sign()`

method.

Here are a few basic example of using the `abs()`

and `neg()`

methods:

```
// Calculating the absolute value
$five = $five->abs();
$five = $negative_five->abs();
// Negating numbers
$negative_five = $five->neg();
$five = $negative_five->neg();
```

The `sign()`

method will return `-1`

if the number is negative, `0`

if the number is zero and `1`

if the number is positive.

```
$true = $five->sign() == 1;
$true = $zero->sign() == 0;
$false = $zero->sign() == -1;
$true = $negative_one->sign() == -1;
```

The value of pi can be obtained up to a scale of 500 by calling the static method `pi()`

and providing the desired `$scale`

.

```
// 3.14
$pi = fNumber::pi(2);
// 3.1415926535897932384626433
$pi = fNumber::pi(25);
```

For some calculations, representing numbers in a base other than base 10 is necessary. The static method `baseConvert()`

allow converting integers between any two bases ranging from base 2 (binary) to base 16 (hexadecimal). Three parameters are required, the integer to convert, the base being converted from and the base being converted to.

```
echo fNumber::baseConvert($five, 10, 2) . "\n";
echo fNumber::baseConvert('10110100110', 2, 16) . "\n";
echo fNumber::baseConvert('10110100110', 2, 8);
```

would output the following

```
101
5A6
2646
```

When formatting numbers in different locales, it will often be the case that the thousands separator and decimal point are different than the one in the United States. The methods `registerFormatCallback()`

and `registerUnformatCallback()`

allow for both creating a different formatting and also removing such formatting when creating a new fNumber object.

```
// Function to format numbers for Italian
function italian_number_format($number, $remove_zero_fraction=FALSE)
{
$parts = explode('.', $number);
$integer = $parts[0];
$fraction = (isset($parts[1])) ? ',' . $parts[1] : '';
if ($remove_zero_fraction && rtrim($fraction, ',0') === '') {
$fraction = '';
}
return number_format($integer, 0, ',', '.') . $fraction;
}
// Function to change a formatted to a plain number
function italian_number_unformat($value)
{
return str_replace(array('.', ','), array('', '.'), $value);
}
fNumber::registerFormatCallback('italian_number_format');
fNumber::registerUnformatCallback('italian_number_unformat');
```