Passed
Pull Request — master (#132)
by Jordan
17:22
created

ImmutableDecimal   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 85
Duplicated Lines 0 %

Test Coverage

Coverage 91.18%

Importance

Changes 0
Metric Value
eloc 35
dl 0
loc 85
ccs 31
cts 34
cp 0.9118
rs 10
c 0
b 0
f 0
wmc 12

2 Methods

Rating   Name   Duplication   Size   Complexity  
A continuousModulo() 0 24 4
B setValue() 0 41 8
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\Numbers;
9
use Samsara\Fermat\Provider\ArithmeticProvider;
10
use Samsara\Fermat\Provider\BaseConversionProvider;
11
use Samsara\Fermat\Types\Base\Interfaces\Numbers\NumberInterface;
12
use Samsara\Fermat\Types\Decimal;
13
use Samsara\Fermat\Types\Base\Interfaces\Numbers\DecimalInterface;
14
15
/**
16
 *
17
 */
18
class ImmutableDecimal extends Decimal
19
{
20
21
    /**
22
     * @param NumberInterface|string|int|float $mod
23
     * @return DecimalInterface
24
     * @throws IntegrityConstraint
25
     * @throws MissingPackage
26
     */
27 41
    public function continuousModulo(NumberInterface|string|int|float $mod): DecimalInterface
28
    {
29
30 41
        $mod = Numbers::makeOrDont(Numbers::IMMUTABLE, $mod);
31
32 41
        $scale = ($this->getScale() < $mod->getScale()) ? $mod->getScale() : $this->getScale();
33
34 41
        $newScale = $scale+2;
35 41
        $thisNum = Numbers::make(Numbers::IMMUTABLE, $this->getValue(NumberBase::Ten), $newScale);
36
37 41
        if (is_object($mod) && method_exists($mod, 'truncateToScale')) {
38 41
            $mod = $mod->truncateToScale($newScale);
39
        } else {
40
            $mod = Numbers::make(Numbers::IMMUTABLE, $mod, $newScale);
41
        }
42
43
44 41
        $multiple = $thisNum->divide($mod, $newScale)->floor();
45
46 41
        $subtract = $mod->multiply($multiple);
47
48 41
        $remainder = $thisNum->subtract($subtract);
49
50 41
        return $remainder->truncateToScale($this->getScale()-1);
51
52
    }
53
54
    /**
55
     * @param string $value
56
     * @param int|null $scale
57
     * @param NumberBase|null $base
58
     * @param bool $setToNewBase
59
     * @return ImmutableDecimal
60
     * @throws IntegrityConstraint
61
     */
62 455
    protected function setValue(string $value, ?int $scale = null, ?NumberBase $base = null, bool $setToNewBase = false): ImmutableDecimal
63
    {
64 455
        $imaginary = false;
65
66 455
        if (str_contains($value, 'i')) {
67 121
            $value = str_replace('i', '', $value);
68 121
            $imaginary = true;
69
        }
70
71 455
        if ((!is_null($base) && $base != NumberBase::Ten)) {
72
            $value = BaseConversionProvider::convertStringToBaseTen($value, $base);
73
        }
74
75 455
        if ($setToNewBase) {
76
            $base = $base ?? NumberBase::Ten;
77
        } else {
78 455
            $base = $this->getBase();
79
        }
80
81 455
        $sign = $this->sign;
82
83 455
        $translated = $this->translateValue($value);
84 455
        $determinedScale = $this->determineScale($translated[1]);
85
86 455
        $this->sign = $sign;
87
88 455
        $determinedScale = $this->getScale() > $determinedScale ? $this->getScale() : $determinedScale;
89
90 455
        $scale = $scale ?? $determinedScale;
91
92 455
        if ($imaginary) {
93 121
            $value .= 'i';
94
        }
95
96 455
        $return = new ImmutableDecimal($value, $scale, $base, true);
97
98 455
        if (isset($this->calcMode)) {
99 212
            $return->setMode($this->calcMode);
0 ignored issues
show
Bug introduced by
It seems like $this->calcMode can also be of type null; however, parameter $mode of Samsara\Fermat\Types\Base\Number::setMode() does only seem to accept Samsara\Fermat\Enums\CalcMode, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

99
            $return->setMode(/** @scrutinizer ignore-type */ $this->calcMode);
Loading history...
100
        }
101
102 455
        return $return;
103
    }
104
105
}