-
-
Notifications
You must be signed in to change notification settings - Fork 6
03. Arithmetic
Arithmetic can be performed on any class that implements the NumberInterface
, and the rules for using arithmetic methods are consistent and straight-forward: you can put any value that is valid for an ImmutableNumber
constructor in, or you can put in any instance of an object that implements NumberInterface
itself.
The following arithmetic methods are available.
This adds the argument to the Value using the ArithmeticProvider
(which uses the BCMath library internally) and returns the newly calculated Value.
When an object that implements DecimalInterface
and another that implements FractionInterface
are added together, the one that is provided as an argument is coerced into the type of original object. For example:
<?php
use Samsara\Fermat\Values\ImmutableNumber;
use Samsara\Fermat\Values\ImmutableFraction;
$five = new ImmutableNumber(5);
$oneQuarter = new ImmutableFraction(1, 4);
echo $five->add($oneQuarter); // Prints: "5.25"
// The asDecimal() method is called on $oneQuarter
echo $oneQuarter->add($five); // Prints: "21/4"
// Calls getValue() on $five and instantiates a new ImmutableFraction
This subtracts the argument from the Value using the ArithmeticProvider
(which uses the BCMath library internally) and returns the newly calculated Value.
When an object that implements DecimalInterface
and another that implements FractionInterface
are subtracted, the one that is provided as an argument is coerced into the type of original object. For example:
<?php
use Samsara\Fermat\Values\ImmutableNumber;
use Samsara\Fermat\Values\ImmutableFraction;
$five = new ImmutableNumber(5);
$oneQuarter = new ImmutableFraction(1, 4);
echo $five->subtract($oneQuarter); // Prints: "4.75"
// The asDecimal() method is called on $oneQuarter
echo $oneQuarter->subtract($five); // Prints: "-19/4"
// Calls getValue() on $five and instantiates a new ImmutableFraction
This multiplies the argument from the Value using the ArithmeticProvider
(which uses the BCMath library internally) and returns the newly calculated Value.
When an object that implements DecimalInterface
and another that implements FractionInterface
are multiplied, the one that is provided as an argument is coerced into the type of original object. For example:
<?php
use Samsara\Fermat\Values\ImmutableNumber;
use Samsara\Fermat\Values\ImmutableFraction;
$five = new ImmutableNumber(5);
$oneQuarter = new ImmutableFraction(1, 4);
echo $five->multiply($oneQuarter); // Prints: "1.25"
// The asDecimal() method is called on $oneQuarter
echo $oneQuarter->multiply($five); // Prints: "5/4"
// Calls getValue() on $five and instantiates a new ImmutableFraction
This divides the argument from the Value using the ArithmeticProvider
(which uses the BCMath library internally) and returns the newly calculated Value.
The $precision argument tells the Value how many decimals of accuracy you want in your division (if that is relevant to the division), and defaults to the precision of the calling object if null. The default precision of a Value, if you do not set it during instantiation, is 10.
When an object that implements DecimalInterface
and another that implements FractionInterface
are divided, the one that is provided as an argument is coerced into the type of original object. For example:
<?php
use Samsara\Fermat\Values\ImmutableNumber;
use Samsara\Fermat\Values\ImmutableFraction;
$five = new ImmutableNumber(5);
$oneQuarter = new ImmutableFraction(1, 4);
echo $five->divide($oneQuarter); // Prints: "20"
// The asDecimal() method is called on $oneQuarter
echo $oneQuarter->divide($five); // Prints: "1/20"
// Calls getValue() on $five and instantiates a new ImmutableFraction
This raises the Value to the power of $num, and will work even if $num has a decimal component. NOTE: This method will only return Real numbers as Values, as Complex numbers are not currently supported.
When an object that implements DecimalInterface
and another that implements FractionInterface
are raised to a power, the one that is provided as an argument is coerced into the type of original object. For example:
<?php
use Samsara\Fermat\Values\ImmutableNumber;
use Samsara\Fermat\Values\ImmutableFraction;
$five = new ImmutableNumber(5);
$oneQuarter = new ImmutableFraction(1, 4);
echo $five->pow($oneQuarter); // Prints: "1.4953487812"
// The asDecimal() method is called on $oneQuarter
// Because $precision was not supplied to the constructor, $precision is 10
echo $oneQuarter->pow($five); // Prints: "1/1024"
// Calls getValue() on $five and instantiates a new ImmutableFraction
This takes the square root of the current object.
<?php
use Samsara\Fermat\Values\ImmutableNumber;
use Samsara\Fermat\Values\ImmutableFraction;
$five = new ImmutableNumber(5);
$oneQuarter = new ImmutableFraction(1, 4);
echo $five->sqrt(); // Prints: "2.2360679775"
// Because $precision was not supplied to the constructor, $precision is 10
echo $oneQuarter->sqrt(); // Prints: "1/2"
Additional arithmetic can be performed on objects that implement the DecimalInterface
, and the rules for using arithmetic methods are the same as with NumberInterface
methods: you can put any value that is valid for an ImmutableNumber
constructor in, or you can put in any instance of an object that implements DecimalInterface
itself.
This takes the factorial of the current Value, however the Value must be a whole number.
<?php
use Samsara\Fermat\Values\ImmutableNumber;
$five = new ImmutableNumber(5);
echo $five->factorial(); // Prints: "120"
This takes the double factorial (x!!) of the current Value. Note: If you are not familiar with this operation, it is NOT the same as taking the factorial twice: (x!)!. Instead it is like taking a factorial where you decrease the number by two instead of one:
10! = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1
10!! = 10 * 8 * 6 * 4 * 2
<?php
use Samsara\Fermat\Values\ImmutableNumber;
$five = new ImmutableNumber(5);
echo $five->doubleFactorial(); // Prints: "15"
This takes the natural log of the current Value, accurate to $precision decimal places.
If the $round argument is true
the last digit will be rounded; if the $round argument is false
the last digit will be truncated. It is important to note that the last digit (prior to rounding) is guaranteed to be accurate, so rounding will actually reduce the precision, in effect, by one. However, it will capture some of the behavior after the precision limit.
<?php
use Samsara\Fermat\Values\ImmutableNumber;
$five = new ImmutableNumber(5);
echo $five->ln(11); // Prints: "1.60943791243"
This takes the log base10 of the current Value, accurate to $precision decimal places.
If the $round argument is true
the last digit will be rounded; if the $round argument is false
the last digit will be truncated. It is important to note that the last digit (prior to rounding) is guaranteed to be accurate, so rounding will actually reduce the precision, in effect, by one. However, it will capture some of the behavior after the precision limit.
<?php
use Samsara\Fermat\Values\ImmutableNumber;
$five = new ImmutableNumber(5);
echo $five->log10(11); // Prints: "0.69897000434"
The ArithmeticProvider
is a wrapper for the BCMath library, and it is ultimately what performs most operations inside the objects that implement NumberInterface
, DecimalInterface
, FractionInterface
, and CoordinateInterface
.
All of its methods are static, and can be accessed without instantiating the class.
All arguments to this provider must be strings which only contain numeric values.
Calls bcadd($number1, $number2)
with a scale setting of 100.
Calls bcsub($left, $right)
with a scale setting of 100.
Calls bcmul($number1, $number2)
with a scale setting of 100.
Calls bcdiv($numerator, $denominator, $precision)
.
Calls bcpow($base, $exponent)
with a scale of 100. Note: Unlike the pow()
method on NumberInterface
objects, the exponent must be a whole number.
Calls bcsqrt($number, $precision)
.
Calls bcmod($number, $modulo)
. Note: Unlike the continuousModulo()
method on DecimalInterface
objects, the modulus must be a whole number.
Calls bccomp($left, $right, $scale)
. Its output format is identical to the compare()
helper method on NumberInterface
objects.
Calls bcpowmod($left, $right, $modulus, $scale)
.
Calls bcmul()
repeatedly to return the factorial. Note: The factorial()
method on DecimalInterface
objects does not use this method, and instead uses gmp_fact()
if the method is available, and makes repeated calls to multiply()
if it is not.