Passed
Branch master (7fff96)
by Jordan
06:01
created

MutableDecimal::setValue()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5.0729

Importance

Changes 0
Metric Value
cc 5
eloc 13
nc 8
nop 4
dl 0
loc 26
ccs 12
cts 14
cp 0.8571
crap 5.0729
rs 9.5222
c 0
b 0
f 0
1
<?php
2
3
namespace Samsara\Fermat\Values;
4
5
use Samsara\Exceptions\SystemError\PlatformError\MissingPackage;
6
use Samsara\Exceptions\UsageError\IntegrityConstraint;
7
use Samsara\Fermat\Enums\NumberBase;
8
use Samsara\Fermat\Provider\BaseConversionProvider;
9
use Samsara\Fermat\Types\Base\Interfaces\Numbers\NumberInterface;
10
use Samsara\Fermat\Types\Decimal;
11
use Samsara\Fermat\Numbers;
12
use Samsara\Fermat\Types\Base\Interfaces\Numbers\DecimalInterface;
13
14
/**
15
 *
16
 */
17
class MutableDecimal extends Decimal
18
{
19
20
    /**
21
     * @throws IntegrityConstraint
22
     * @throws MissingPackage
23
     */
24 1
    public function continuousModulo(NumberInterface|string|int|float $mod): DecimalInterface
25
    {
26
27 1
        $mod = Numbers::makeOrDont(Numbers::IMMUTABLE, $mod, $this->scale+1);
28 1
        $oldNum = Numbers::make(Numbers::IMMUTABLE, $this->getValue(NumberBase::Ten), $this->scale+1);
29
30 1
        $multiple = $oldNum->divide($mod)->floor();
31 1
        $multipleCeil = $multiple->ceil();
32 1
        $digits = $multipleCeil->subtract($multiple)->numberOfLeadingZeros();
33
34 1
        if ($digits >= $this->getScale()) {
35
            $multiple = $multipleCeil;
36
        } else {
37 1
            $multiple = $multiple->floor();
38
        }
39
40 1
        $remainder = $oldNum->subtract($mod->multiply($multiple));
41
42 1
        return Numbers::make(Numbers::MUTABLE, $remainder->truncate($this->scale-1)->getValue(NumberBase::Ten), $this->scale-1, $this->getBase());
43
44
    }
45
46
    /**
47
     * @param string $value
48
     * @param int|null $scale
49
     * @param NumberBase|null $base
50
     * @param bool $setToNewBase
51
     * @return MutableDecimal
52
     */
53 423
    protected function setValue(string $value, ?int $scale = null, ?NumberBase $base = null, bool $setToNewBase = false): self
54
    {
55 423
        $imaginary = false;
56
57 423
        if (str_contains($value, 'i')) {
58 20
            $value = str_replace('i', '', $value);
59 20
            $imaginary = true;
60
        }
61
62 423
        if (!is_null($base) && $base != NumberBase::Ten) {
63
            $value = BaseConversionProvider::convertStringToBaseTen($value, $base);
64
        }
65
66 423
        $this->imaginary = $imaginary;
67
68 423
        if ($setToNewBase) {
69
            $this->base = $base ?? $this->getBase();
70
        }
71
72 423
        $this->value = $this->translateValue($value);
73
74 423
        $scale = $scale ?? $this->getScale();
75
76 423
        $this->scale = $this->determineScale($this->getDecimalPart(), $scale);
77
78 423
        return $this;
79
    }
80
81
}