JEMBOT MAWOT Bypass Shell
<?php
/**
* This file is part of the PrestaShop\Decimal package
*
* @author PrestaShop SA <contact@prestashop.com>
* @license https://opensource.org/licenses/MIT MIT License
*/
namespace PrestaShop\Decimal\Operation;
use PrestaShop\Decimal\DecimalNumber;
use PrestaShop\Decimal\Exception\DivisionByZeroException;
/**
* Computes the division between two decimal numbers.
*/
class Division
{
public const DEFAULT_PRECISION = 6;
/**
* Performs the division.
*
* A target maximum precision is required in order to handle potential infinite number of decimals
* (e.g. 1/3 = 0.3333333...).
*
* If the division yields more decimal positions than the requested precision,
* the remaining decimals are truncated, with **no rounding**.
*
* @param DecimalNumber $a Dividend
* @param DecimalNumber $b Divisor
* @param int $precision Maximum decimal precision
*
* @return DecimalNumber Result of the division
*
* @throws DivisionByZeroException
*/
public function compute(DecimalNumber $a, DecimalNumber $b, $precision = self::DEFAULT_PRECISION)
{
if (function_exists('bcdiv')) {
return $this->computeUsingBcMath($a, $b, $precision);
}
return $this->computeWithoutBcMath($a, $b, $precision);
}
/**
* Performs the division using BC Math
*
* @param DecimalNumber $a Dividend
* @param DecimalNumber $b Divisor
* @param int $precision Maximum decimal precision
*
* @return DecimalNumber Result of the division
*
* @throws DivisionByZeroException
*/
public function computeUsingBcMath(DecimalNumber $a, DecimalNumber $b, $precision = self::DEFAULT_PRECISION)
{
if ((string) $b === '0') {
throw new DivisionByZeroException();
}
return new DecimalNumber((string) bcdiv($a, $b, $precision));
}
/**
* Performs the division without BC Math
*
* @param DecimalNumber $a Dividend
* @param DecimalNumber $b Divisor
* @param int $precision Maximum decimal precision
*
* @return DecimalNumber Result of the division
*
* @throws DivisionByZeroException
*/
public function computeWithoutBcMath(DecimalNumber $a, DecimalNumber $b, $precision = self::DEFAULT_PRECISION)
{
$bString = (string) $b;
if ('0' === $bString) {
throw new DivisionByZeroException();
}
$aString = (string) $a;
// 0 as dividend always yields 0
if ('0' === $aString) {
return $a;
}
// 1 as divisor always yields the dividend
if ('1' === $bString) {
return $a;
}
// -1 as divisor always yields the the inverted dividend
if ('-1' === $bString) {
return $a->invert();
}
// if dividend and divisor are equal, the result is always 1
if ($a->equals($b)) {
return new DecimalNumber('1');
}
$aPrecision = $a->getPrecision();
$bPrecision = $b->getPrecision();
$maxPrecision = max($aPrecision, $bPrecision);
if ($maxPrecision > 0) {
// make $a and $b integers by multiplying both by 10^(maximum number of decimals)
$a = $a->toMagnitude($maxPrecision);
$b = $b->toMagnitude($maxPrecision);
}
return $this->integerDivision($a, $b, $precision);
}
/**
* Computes the division between two integer DecimalNumbers
*
* @param DecimalNumber $a Dividend
* @param DecimalNumber $b Divisor
* @param int $precision Maximum number of decimals to try
*
* @return DecimalNumber
*/
private function integerDivision(DecimalNumber $a, DecimalNumber $b, $precision)
{
$dividend = $a->getCoefficient();
$divisor = new DecimalNumber($b->getCoefficient());
$dividendLength = strlen($dividend);
$result = '';
$exponent = 0;
$currentSequence = '';
for ($i = 0; $i < $dividendLength; ++$i) {
// append digits until we get a number big enough to divide
$currentSequence .= $dividend[$i];
if ($currentSequence < $divisor) {
if (!empty($result)) {
$result .= '0';
}
} else {
// subtract divisor as many times as we can
$remainder = new DecimalNumber($currentSequence);
$multiple = 0;
do {
++$multiple;
$remainder = $remainder->minus($divisor);
} while ($remainder->isGreaterOrEqualThan($divisor));
$result .= (string) $multiple;
// reset sequence to the reminder
$currentSequence = (string) $remainder;
}
// add up to $precision decimals
if ($currentSequence > 0 && $i === $dividendLength - 1 && $precision > 0) {
// "borrow" up to $precision digits
--$precision;
$dividend .= '0';
++$dividendLength;
++$exponent;
}
}
$sign = ($a->isNegative() xor $b->isNegative()) ? '-' : '';
return new DecimalNumber($sign . $result, $exponent);
}
}
xxxxx1.0, XXX xxxx