<commit_before><?php

declare(strict_types=1);

namespace Brick\Math\Internal\Calculator;

use Brick\Math\Internal\Calculator;

/**
 * Calculator implementation using only native PHP code.
 *
 * @internal
 */
class NativeCalculator extends Calculator
{
    /**
     * The max number of digits the platform can natively add, subtract or divide without overflow.
     *
     * @var int
     */
    private $maxDigitsAddDiv = 0;

    /**
     * The max number of digits the platform can natively multiply without overflow.
     *
     * @var int
     */
    private $maxDigitsMul = 0;

    /**
     * Class constructor.
     *
     * @codeCoverageIgnore
     */
    public function __construct()
    {
        switch (PHP_INT_SIZE) {
            case 4:
                $this->maxDigitsAddDiv = 9;
                $this->maxDigitsMul = 4;
                break;

            case 8:
                $this->maxDigitsAddDiv = 18;
                $this->maxDigitsMul = 9;
                break;
        }
    }

    /**
     * {@inheritdoc}
     */
    public function add(string $a, string $b) : string
    {
        if ($a === '0') {
            return $b;
        }

        if ($b === '0') {
            return $a;
        }

        $this->init($a, $b, $aDig, $bDig, $aNeg, $bNeg, $aLen, $bLen);

        if ($aLen <= $this->maxDigitsAddDiv && $bLen <= $this->maxDigitsAddDiv) {
            return (string) ((int) $a + (int) $b);
        }

        if ($aNeg === $bNeg) {
            $result = $this->doAdd($aDig, $bDig, $aLen, $bLen);
        } else {
            $result = $this->doSub($aDig, $bDig, $aLen, $bLen);
        }

        if ($aNeg) {
            $result = $this->neg($result);
        }

        return $result;
    }

    /**
     * {@inheritdoc}
     */
    public function sub(string $a, string $b) : string
    {
        return $this->add($a, $this->neg($b));
    }

    /**
     * {@inheritdoc}
     */
    public function mul(string $a, string $b) : string
    {
        if ($a === '0' || $b === '0') {
            return '0';
        }

        if ($a === '1') {
            return $b;
        }

        if ($b === '1') {
            return $a;
        }

        if ($a === '-1') {
            return $this->neg($b);
        }

        if ($b === '-1') {
            return $this->neg($a);
        }

        $this->init($a, $b, $aDig, $bDig, $aNeg, $bNeg, $aLen, $bLen);

        if ($aLen <= $this->maxDigitsMul && $bLen <= $this->maxDigitsMul) {
            return (string) ((int) $a * (int) $b);
        }

        $result = $this->doMul($aDig, $bDig, $aLen, $bLen);

        if ($aNeg !== $bNeg) {
            $result = $this->neg($result);
        }

        return $result;
    }

    /**
     * {@inheritdoc}
     */
    public function divQ(string $a, string $b) : string
    {
        return $this->divQR($a, $b)[0];
    }

    /**
     * {@inheritdoc}
     */
    public function divR(string $a, string $b): string
    {
        return $this->divQR($a, $b)[1];
    }

    /**
     * {@inheritdoc}
     */
    public function divQR(string $a, string $b) : array
    {
        if ($a === '0') {
            return ['0', '0'];
        }

        if ($a === $b) {
            return ['1', '0'];
        }

        if ($b === '1') {
            return [$a, '0'];
        }

        if ($b === '-1') {
            return [$this->neg($a), '0'];
        }

        $this->init($a, $b, $aDig, $bDig, $aNeg, $bNeg, $aLen, $bLen);

        if ($aLen <= $this->maxDigitsAddDiv && $bLen <= $this->maxDigitsAddDiv) {
            $a = (int) $a;
            $b = (int) $b;

            $r = $a % $b;
            $q = ($a - $r) / $b;

            $q = (string) $q;
            $r = (string) $r;

            return [$q, $r];
        }

        [$q, $r] = $this->doDiv($aDig, $bDig, $aLen, $bLen);

        if ($aNeg !== $bNeg) {
            $q = $this->neg($q);
        }<commit_msg>NativeCalculator::mul() can now handle multiplication natively in more cases<commit_after><?php

declare(strict_types=1);

namespace Brick\Math\Internal\Calculator;

use Brick\Math\Internal\Calculator;

/**
 * Calculator implementation using only native PHP code.
 *
 * @internal
 */
class NativeCalculator extends Calculator
{
    /**
     * The max number of digits the platform can natively add, subtract, multiply or divide without overflow.
     * For multiplication, this represents the max sum of the lengths of both operands.
     *
     * @var int
     */
    private $maxDigits = 0;

    /**
     * Class constructor.
     *
     * @codeCoverageIgnore
     */
    public function __construct()
    {
        switch (PHP_INT_SIZE) {
            case 4:
                $this->maxDigits = 9;
                break;

            case 8:
                $this->maxDigits = 18;
                break;
        }
    }

    /**
     * {@inheritdoc}
     */
    public function add(string $a, string $b) : string
    {
        if ($a === '0') {
            return $b;
        }

        if ($b === '0') {
            return $a;
        }

        $this->init($a, $b, $aDig, $bDig, $aNeg, $bNeg, $aLen, $bLen);

        if ($aLen <= $this->maxDigits && $bLen <= $this->maxDigits) {
            return (string) ((int) $a + (int) $b);
        }

        if ($aNeg === $bNeg) {
            $result = $this->doAdd($aDig, $bDig, $aLen, $bLen);
        } else {
            $result = $this->doSub($aDig, $bDig, $aLen, $bLen);
        }

        if ($aNeg) {
            $result = $this->neg($result);
        }

        return $result;
    }

    /**
     * {@inheritdoc}
     */
    public function sub(string $a, string $b) : string
    {
        return $this->add($a, $this->neg($b));
    }

    /**
     * {@inheritdoc}
     */
    public function mul(string $a, string $b) : string
    {
        if ($a === '0' || $b === '0') {
            return '0';
        }

        if ($a === '1') {
            return $b;
        }

        if ($b === '1') {
            return $a;
        }

        if ($a === '-1') {
            return $this->neg($b);
        }

        if ($b === '-1') {
            return $this->neg($a);
        }

        $this->init($a, $b, $aDig, $bDig, $aNeg, $bNeg, $aLen, $bLen);

        if ($aLen + $bLen <= $this->maxDigits) {
            return (string) ((int) $a * (int) $b);
        }

        $result = $this->doMul($aDig, $bDig, $aLen, $bLen);

        if ($aNeg !== $bNeg) {
            $result = $this->neg($result);
        }

        return $result;
    }

    /**
     * {@inheritdoc}
     */
    public function divQ(string $a, string $b) : string
    {
        return $this->divQR($a, $b)[0];
    }

    /**
     * {@inheritdoc}
     */
    public function divR(string $a, string $b): string
    {
        return $this->divQR($a, $b)[1];
    }

    /**
     * {@inheritdoc}
     */
    public function divQR(string $a, string $b) : array
    {
        if ($a === '0') {
            return ['0', '0'];
        }

        if ($a === $b) {
            return ['1', '0'];
        }

        if ($b === '1') {
            return [$a, '0'];
        }

        if ($b === '-1') {
            return [$this->neg($a), '0'];
        }

        $this->init($a, $b, $aDig, $bDig, $aNeg, $bNeg, $aLen, $bLen);

        if ($aLen <= $this->maxDigits && $bLen <= $this->maxDigits) {
            $a = (int) $a;
            $b = (int) $b;

            $r = $a % $b;
            $q = ($a - $r) / $b;

            $q = (string) $q;
            $r = (string) $r;

            return [$q, $r];
        }

        [$q, $r] = $this->doDiv($aDig, $bDig, $aLen, $bLen);

        if ($aNeg !== $bNeg) {
            $q = $this->neg($q);
        }
{'fraction_non_alphanumeric': 0.18800627123072902, 'fraction_numerical': 0.007447086490723805, 'mean_word_length': 1.4194058154235145, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 54, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4032840', 'n_tokens_mistral': 2725, 'n_tokens_neox': 2595, 'n_words': 622}