ImmutableDecimal::setValue()   B
last analyzed

Complexity

Conditions 8
Paths 64

Size

Total Lines 41
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 8.048

Importance

Changes 0
Metric Value
cc 8
dl 0
loc 41
ccs 20
cts 22
cp 0.9091
crap 8.048
rs 8.4444
c 0
b 0
f 0
eloc 22
nc 64
nop 4
1
<?php
2
3
namespace Samsara\Fermat\Core\Values;
4
5
use Samsara\Exceptions\SystemError\PlatformError\MissingPackage;
6
use Samsara\Exceptions\UsageError\IntegrityConstraint;
7
use Samsara\Fermat\Core\Enums\NumberBase;
8
use Samsara\Fermat\Core\Numbers;
9
use Samsara\Fermat\Core\Provider\ArithmeticProvider;
10
use Samsara\Fermat\Core\Provider\BaseConversionProvider;
11
use Samsara\Fermat\Core\Types\Base\Interfaces\Numbers\NumberInterface;
0 ignored issues
show
Bug introduced by
The type Samsara\Fermat\Core\Type...Numbers\NumberInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use Samsara\Fermat\Core\Types\Decimal;
0 ignored issues
show
Bug introduced by
The type Samsara\Fermat\Core\Types\Decimal was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Samsara\Fermat\Core\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 906
    public function continuousModulo(NumberInterface|string|int|float $mod): DecimalInterface
28
    {
29
30 906
        $mod = Numbers::makeOrDont(Numbers::IMMUTABLE, $mod);
31
32 906
        $scale = ($this->getScale() < $mod->getScale()) ? $mod->getScale() : $this->getScale();
33
34 906
        $newScale = $scale+2;
35 906
        $thisNum = Numbers::make(Numbers::IMMUTABLE, $this->getValue(NumberBase::Ten), $newScale);
36
37 906
        $mod = $mod->truncateToScale($newScale);
38
39 906
        $multiple = $thisNum->divide($mod, $newScale);
40 906
        $multipleCeil = $multiple->ceil();
41 906
        $digits = $multipleCeil->subtract($multiple)->numberOfLeadingZeros();
42
43 906
        if ($digits >= $this->getScale()) {
44 114
            $multiple = $multipleCeil;
45
        } else {
46 842
            $multiple = $multiple->floor();
47
        }
48
49 906
        $subtract = $mod->multiply($multiple);
50
51 906
        $remainder = $thisNum->subtract($subtract);
52
53 906
        return $remainder->truncateToScale($this->getScale()-1);
54
55
    }
56
57
    /**
58
     * @param string $value
59
     * @param int|null $scale
60
     * @param NumberBase|null $base
61
     * @param bool $setToNewBase
62
     * @return ImmutableDecimal
63
     * @throws IntegrityConstraint
64
     */
65 3143
    protected function setValue(string $value, ?int $scale = null, ?NumberBase $base = null, bool $setToNewBase = false): ImmutableDecimal
66
    {
67 3143
        $imaginary = false;
68
69 3143
        if (str_contains($value, 'i')) {
70 310
            $value = str_replace('i', '', $value);
71 310
            $imaginary = true;
72
        }
73
74 3143
        if ((!is_null($base) && $base != NumberBase::Ten)) {
75
            $value = BaseConversionProvider::convertStringToBaseTen($value, $base);
76
        }
77
78 3143
        if ($setToNewBase) {
79
            $base = $base ?? NumberBase::Ten;
80
        } else {
81 3143
            $base = $this->getBase();
82
        }
83
84 3143
        $sign = $this->sign;
85
86 3143
        $translated = $this->translateValue($value);
87 3143
        $determinedScale = $this->determineScale($translated[1]);
88
89 3143
        $this->sign = $sign;
0 ignored issues
show
Bug Best Practice introduced by
The property sign does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
90
91 3143
        $determinedScale = $this->getScale() > $determinedScale ? $this->getScale() : $determinedScale;
92
93 3143
        $scale = $scale ?? $determinedScale;
94
95 3143
        if ($imaginary) {
96 310
            $value .= 'i';
97
        }
98
99 3143
        $return = new ImmutableDecimal($value, $scale, $base, true);
100
101 3143
        if (isset($this->calcMode)) {
102 1308
            $return->setMode($this->calcMode);
103
        }
104
105 3143
        return $return;
106
    }
107
108
}