Passed
Pull Request — master (#4115)
by Owen
15:19
created

Trunc::evaluate()   B

Complexity

Conditions 9
Paths 12

Size

Total Lines 36
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 9

Importance

Changes 0
Metric Value
eloc 24
c 0
b 0
f 0
dl 0
loc 36
rs 8.0555
ccs 9
cts 9
cp 1
cc 9
nc 12
nop 2
crap 9
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
4
5
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
6
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
7
8
class Trunc
9
{
10
    use ArrayEnabled;
11
12
    /**
13
     * TRUNC.
14
     *
15
     * Truncates value to the number of fractional digits by number_digits.
16
     * This will probably not be the precise result in the unlikely
17
     * event that the number of digits to the left of the decimal
18
     * plus the number of digits to the right exceeds PHP_FLOAT_DIG
19
     * (or possibly that value minus 1).
20
     * Excel is unlikely to do any better.
21
     *
22
     * @param array|float $value Or can be an array of values
23
     * @param array|int $digits Or can be an array of values
24 30
     *
25
     * @return array|float|string Truncated value, or a string containing an error
26 30
     *         If an array of numbers is passed as an argument, then the returned result will also be an array
27 5
     *            with the same dimensions
28
     */
29
    public static function evaluate(array|float|string|null $value = 0, array|int|string $digits = 0): array|float|string
30
    {
31 30
        if (is_array($value) || is_array($digits)) {
32 28
            return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $digits);
33 3
        }
34 3
35
        try {
36
            $value = Helpers::validateNumericNullBool($value);
37 27
            $digits = Helpers::validateNumericNullSubstitution($digits, null);
38
        } catch (Exception $e) {
39
            return $e->getMessage();
40 27
        }
41
42 27
        if ($value == 0) {
43 2
            return $value;
44
        }
45
46 25
        if ($value >= 0) {
47
            $minusSign = '';
48
        } else {
49
            $minusSign = '-';
50
            $value = -$value;
51
        }
52
        $digits = (int) floor($digits);
53
        if ($digits < 0) {
54
            $power = (int) (10 ** -$digits);
55
            $result = intdiv((int) floor($value), $power) * $power;
56
57
            return ($minusSign === '') ? $result : -$result;
58
        }
59
        $decimals = PHP_FLOAT_DIG - strlen((string) (int) $value);
60
        $resultString = ($decimals < 0) ? sprintf('%F', $value) : sprintf('%.' . $decimals . 'F', $value);
61
        $regExp = '/([.]\\d{' . $digits . '})\\d+$/';
62
        $result = $minusSign . (preg_replace($regExp, '$1', $resultString) ?? $resultString);
63
64
        return (float) $result;
65
    }
66
}
67