"Ceils" the Decimal to have at most $scale digits after the point
@param  integer $scale
@return Decimal
438103
public function ceil($scale = 0): Decimal
    {
        if ($scale >= $this->scale) {
            return $this;
        }

        if ($this->isNegative()) {
            return self::fromString(\bcadd($this->value, '0', $scale));
        }

        return $this->innerTruncate($scale);
    }
842924
public function sub(Decimal $b, int $scale = null): Decimal
    {
        self::paramsValidation($b, $scale);

        return self::fromString(
            \bcsub($this->value, $b->value, \max($this->scale, $b->scale)),
            $scale
        );
    }
1055238
public static function getPercentage($base, $divider, $scale = 2, $string = false)
    {
        if (0 === $divider) {
            return '-';
        }

        $value = round(($base / $divider) * 100, $scale);
        if (false === $string) {
            return $value;
        }

        return sprintf('%s%%', number_format($value, $scale));
    }
1199565
public function mod(Decimal $d, int $scale = null): Decimal
    {
        $div = $this->div($d, 1)->floor();
        return $this->sub($div->mul($d), $scale);
    }
69725
private function valueWithMinScale(int $scale) : string
    {
        $value = $this->value;

        if ($this->value !== '0' && $scale > $this->scale) {
            $value .= \str_repeat('0', $scale - $this->scale);
        }

        return $value;
    }
55566
public function sin(int $scale = null): Decimal
    {
        // First normalise the number in the [0, 2PI] domain
        $x = $this->mod(DecimalConstants::PI()->mul(Decimal::fromString("2")));

        // PI has only 32 significant numbers
        $scale = (null === $scale) ? 32 : $scale;

        return self::factorialSerie(
            $x,
            DecimalConstants::zero(),
            function ($i) {
                return ($i % 2 === 1) ? (
                ($i % 4 === 1) ? DecimalConstants::one() : DecimalConstants::negativeOne()
                ) : DecimalConstants::zero();
            },
            $scale
        );
    }
162980
public function Gt( $number, $scale = false )
	{
		$result = $this->Compare( $number, $scale );
		if ( $result === false ) return false;
		return $result == 1;
	}
517515
public function log10(int $scale = null): Decimal
    {
        if ($this->isNegative()) {
            throw new \DomainException(
                "Decimal can't handle logarithms of negative numbers (it's only for real numbers)."
            );
        } elseif ($this->isZero()) {
            throw new \DomainException(
                "Decimal can't represent infinite numbers."
            );
        }

        return self::fromString(
            self::innerLog10($this->value, $this->scale, $scale !== null ? $scale+1 : $this->scale+1),
            $scale
        );
    }
637212
public function subtotal($decimals = null, $decimalPoint = null, $thousandSeperator = null)
    {
        return $this->numberFormat($this->subtotal, $decimals, $decimalPoint, $thousandSeperator);
    }
697832
public function pow(Decimal $b, int $scale = null): Decimal
    {
        if ($this->isZero()) {
            if ($b->isPositive()) {
                return Decimal::fromDecimal($this, $scale);
            } else {
                throw new \DomainException("zero can't be powered to zero or negative numbers.");
            }
        } elseif ($b->isZero()) {
            return DecimalConstants::One();
        } else if ($b->isNegative()) {
            return DecimalConstants::One()->div(
                $this->pow($b->additiveInverse(), max($scale, self::DEFAULT_SCALE)),
                max($scale, self::DEFAULT_SCALE)
            );
        } elseif (0 === $b->scale) {
            $pow_scale = \max($this->scale, $b->scale, $scale ?? 0);

            return self::fromString(
                \bcpow($this->value, $b->value, $pow_scale+1),
                $pow_scale
            );
        } else {
            if ($this->isPositive()) {
                $pow_scale = \max($this->scale, $b->scale, $scale ?? 0);

                $truncated_b = \bcadd($b->value, '0', 0);
                $remaining_b = \bcsub($b->value, $truncated_b, $b->scale);

                $first_pow_approx = \bcpow($this->value, $truncated_b, $pow_scale+1);
                $intermediate_root = self::innerPowWithLittleExponent(
                    $this->value,
                    $remaining_b,
                    $b->scale,
                    $pow_scale+1
                );

                return Decimal::fromString(
                    \bcmul($first_pow_approx, $intermediate_root, $pow_scale+1),
                    $pow_scale
                );
            } else { // elseif ($this->isNegative())
                if (!$b->isInteger()) {
                    throw new NotImplementedError(
                        "Usually negative numbers can't be powered to non integer numbers. " .
                        "The cases where is possible are not implemented."
                    );
                }

                return (\preg_match('/^[+\-]?[0-9]*[02468](\.0+)?$/', $b->value, $captures) === 1)
                    ? $this->additiveInverse()->pow($b, $scale)                      // $b is an even number
                    : $this->additiveInverse()->pow($b, $scale)->additiveInverse();  // $b is an odd number
            }
        }
    }
560071
public function isLessOrEqualTo(Decimal $b, int $scale = null): bool
    {
        $comparisonResult = $this->comp($b, $scale);

        return $comparisonResult === -1 || $comparisonResult === 0;
    }
1249625
public function float($column, $precision = 8, $scale = 2)
    {
        return $this->table->addColumn($column, Type::FLOAT, compact('precision', 'scale'));
    }
721614
public Decimal toDecimal(int precision, int scale) {
		ensureMaterialized();
		if (precision > Decimal.MAX_LONG_DIGITS || this.sizeInBytes > Decimal.MAX_LONG_DIGITS) {
			return toDecimalSlow(precision, scale);
		}

		// Data in Decimal is stored by one long value if `precision` <= Decimal.MAX_LONG_DIGITS.
		// In this case we can directly extract the value from memory segment.
		int size = getSegments()[0].size();
		SegmentAndOffset segmentAndOffset = startSegmentAndOffset(size);
		int totalOffset = 0;

		// Remove white spaces at the beginning
		byte b = 0;
		while (totalOffset < this.sizeInBytes) {
			b = segmentAndOffset.value();
			if (b != ' ' && b != '\n' && b != '\t') {
				break;
			}
			totalOffset++;
			segmentAndOffset.nextByte(size);
		}
		if (totalOffset == this.sizeInBytes) {
			// all whitespaces
			return null;
		}

		// ======= Significand part begin =======
		final boolean negative = b == '-';
		if (negative || b == '+') {
			segmentAndOffset.nextByte(size);
			totalOffset++;
			if (totalOffset == this.sizeInBytes) {
				// only contains prefix plus/minus
				return null;
			}
		}

		long significand = 0;
		int exp = 0;
		int significandLen = 0, pointPos = -1;

		while (totalOffset < this.sizeInBytes) {
			b = segmentAndOffset.value();
			totalOffset++;
			segmentAndOffset.nextByte(size);

			if (b >= '0' && b <= '9') {
				// No need to worry about overflow, because this.sizeInBytes <= Decimal.MAX_LONG_DIGITS
				significand = significand * 10 + (b - '0');
				significandLen++;
			} else if (b == '.') {
				if (pointPos >= 0) {
					// More than one decimal point
					return null;
				}
				pointPos = significandLen;
			} else {
				break;
			}
		}

		if (pointPos < 0) {
			pointPos = significandLen;
		}
		if (negative) {
			significand = -significand;
		}
		// ======= Significand part end =======

		// ======= Exponential part begin =======
		if ((b == 'e' || b == 'E') && totalOffset < this.sizeInBytes) {
			b = segmentAndOffset.value();
			final boolean expNegative = b == '-';
			if (expNegative || b == '+') {
				segmentAndOffset.nextByte(size);
				totalOffset++;
				if (totalOffset == this.sizeInBytes) {
					return null;
				}
			}

			int expDigits = 0;
			// As `precision` <= 18, value absolute range is limited to 10^-18 ~ 10^18.
			// The worst case is <18-digits>E-36
			final int expStopValue = 40;

			while (totalOffset < this.sizeInBytes) {
				b = segmentAndOffset.value();
				totalOffset++;
				segmentAndOffset.nextByte(size);

				if (b >= '0' && b <= '9') {
					// No need to worry about larger exponents,
					// because they will produce overflow or underflow
					if (expDigits < expStopValue) {
						expDigits = expDigits * 10 + (b - '0');
					}
				} else {
					break;
				}
			}

			if (expNegative) {
				expDigits = -expDigits;
			}
			exp += expDigits;
		}
		exp -= significandLen - pointPos;
		// ======= Exponential part end =======

		// Check for invalid character at the end
		while (totalOffset < this.sizeInBytes) {
			b = segmentAndOffset.value();
			totalOffset++;
			segmentAndOffset.nextByte(size);
			// White spaces are allowed at the end
			if (b != ' ' && b != '\n' && b != '\t') {
				return null;
			}
		}

		// Round exp to scale
		int change = exp + scale;
		if (significandLen + change > precision) {
			// Overflow
			return null;
		}
		if (change >= 0) {
			significand *= Decimal.POW10[change];
		} else {
			int k = negative ? -5 : 5;
			significand = (significand + k * Decimal.POW10[-change - 1]) / Decimal.POW10[-change];
		}
		return Decimal.fromLong(significand, precision, scale);
	}
1292961
private function mul($s1, $s2, $scale) {
        if ($this->bcmath) return bcmul($s1, $s2, $scale);
        else return $this->scale($s1 * $s2, $scale);
    }
1262663
public function minus(Decimal $that) : Decimal
    {
        $this->scaleValues($this, $that, $a, $b);

        $value = $a - $b;

        if (is_float($value)) {
            throw new \RangeException('The subtraction result overflows.');
        }

        $scale = max($this->scale, $that->scale);

        while ($scale !== 0) {
            if ($value % 10 !== 0) {
                break;
            }

            $value /= 10;
            $scale--;
        }

        return new Decimal($value, $scale);
    }
759956
public function scale($scale)
    {
        $width  = $this->getSourceWidth() * $scale / 100;
        $height = $this->getSourceHeight() * $scale / 100;

        $this->resize($width, $height, true);

        return $this;
    }
176995
private function round($number)
    {
        if (null !== $this->scale && null !== $this->roundingMode) {
            // shift number to maintain the correct scale during rounding
            $roundingCoef = pow(10, $this->scale);
            // string representation to avoid rounding errors, similar to bcmul()
            $number = (string) ($number * $roundingCoef);

            switch ($this->roundingMode) {
                case self::ROUND_CEILING:
                    $number = ceil($number);
                    break;
                case self::ROUND_FLOOR:
                    $number = floor($number);
                    break;
                case self::ROUND_UP:
                    $number = $number > 0 ? ceil($number) : floor($number);
                    break;
                case self::ROUND_DOWN:
                    $number = $number > 0 ? floor($number) : ceil($number);
                    break;
                case self::ROUND_HALF_EVEN:
                    $number = round($number, 0, PHP_ROUND_HALF_EVEN);
                    break;
                case self::ROUND_HALF_UP:
                    $number = round($number, 0, PHP_ROUND_HALF_UP);
                    break;
                case self::ROUND_HALF_DOWN:
                    $number = round($number, 0, PHP_ROUND_HALF_DOWN);
                    break;
            }

            $number /= $roundingCoef;
        }

        return $number;
    }