Passed
Push — master ( 4b8292...9204d2 )
by Mark
10:15
created

Floor::precise()   A

Complexity

Conditions 2
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 3
nop 2
dl 0
loc 10
ccs 6
cts 6
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
4
5
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
6
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
7
8
class Floor
9
{
10 4
    private static function floorCheck1Arg(): void
11
    {
12 4
        $compatibility = Functions::getCompatibilityMode();
13 4
        if ($compatibility === Functions::COMPATIBILITY_EXCEL) {
14 2
            throw new Exception('Excel requires 2 arguments for FLOOR');
15
        }
16 2
    }
17
18
    /**
19
     * FLOOR.
20
     *
21
     * Rounds number down, toward zero, to the nearest multiple of significance.
22
     *
23
     * Excel Function:
24
     *        FLOOR(number[,significance])
25
     *
26
     * @param mixed $number Expect float. Number to round
27
     * @param mixed $significance Expect float. Significance
28
     *
29
     * @return float|string Rounded Number, or a string containing an error
30
     */
31 24
    public static function floor($number, $significance = null)
32
    {
33 24
        if ($significance === null) {
34 4
            self::floorCheck1Arg();
35
        }
36
37
        try {
38 22
            $number = Helpers::validateNumericNullBool($number);
39 20
            $significance = Helpers::validateNumericNullSubstitution($significance, ($number < 0) ? -1 : 1);
40 2
        } catch (Exception $e) {
41 2
            return $e->getMessage();
42
        }
43
44 20
        return self::argumentsOk((float) $number, (float) $significance);
45
    }
46
47
    /**
48
     * FLOOR.MATH.
49
     *
50
     * Round a number down to the nearest integer or to the nearest multiple of significance.
51
     *
52
     * Excel Function:
53
     *        FLOOR.MATH(number[,significance[,mode]])
54
     *
55
     * @param mixed $number Number to round
56
     * @param mixed $significance Significance
57
     * @param mixed $mode direction to round negative numbers
58
     *
59
     * @return float|string Rounded Number, or a string containing an error
60
     */
61 28
    public static function math($number, $significance = null, $mode = 0)
62
    {
63
        try {
64 28
            $number = Helpers::validateNumericNullBool($number);
65 26
            $significance = Helpers::validateNumericNullSubstitution($significance, ($number < 0) ? -1 : 1);
66 26
            $mode = Helpers::validateNumericNullSubstitution($mode, null);
67 2
        } catch (Exception $e) {
68 2
            return $e->getMessage();
69
        }
70
71 26
        return self::argsOk((float) $number, (float) $significance, (int) $mode);
72
    }
73
74
    /**
75
     * FLOOR.PRECISE.
76
     *
77
     * Rounds number down, toward zero, to the nearest multiple of significance.
78
     *
79
     * Excel Function:
80
     *        FLOOR.PRECISE(number[,significance])
81
     *
82
     * @param float $number Number to round
83
     * @param float $significance Significance
84
     *
85
     * @return float|string Rounded Number, or a string containing an error
86
     */
87 22
    public static function precise($number, $significance = 1)
88
    {
89
        try {
90 22
            $number = Helpers::validateNumericNullBool($number);
91 20
            $significance = Helpers::validateNumericNullSubstitution($significance, null);
92 3
        } catch (Exception $e) {
93 3
            return $e->getMessage();
94
        }
95
96 19
        return self::argumentsOkPrecise((float) $number, (float) $significance);
97
    }
98
99
    /**
100
     * Avoid Scrutinizer problems concerning complexity.
101
     *
102
     * @return float|string
103
     */
104 19
    private static function argumentsOkPrecise(float $number, float $significance)
105
    {
106 19
        if ($significance == 0.0) {
107 1
            return Functions::DIV0();
108
        }
109 18
        if ($number == 0.0) {
110 3
            return 0.0;
111
        }
112
113 15
        return floor($number / abs($significance)) * abs($significance);
114
    }
115
116
    /**
117
     * Avoid Scrutinizer complexity problems.
118
     *
119
     * @return float|string Rounded Number, or a string containing an error
120
     */
121 26
    private static function argsOk(float $number, float $significance, int $mode)
122
    {
123 26
        if (!$significance) {
124 1
            return Functions::DIV0();
125
        }
126 25
        if (!$number) {
127 4
            return 0.0;
128
        }
129 21
        if (self::floorMathTest($number, $significance, $mode)) {
130 6
            return ceil($number / $significance) * $significance;
131
        }
132
133 15
        return floor($number / $significance) * $significance;
134
    }
135
136
    /**
137
     * Let FLOORMATH complexity pass Scrutinizer.
138
     */
139 21
    private static function floorMathTest(float $number, float $significance, int $mode): bool
140
    {
141 21
        return Helpers::returnSign($significance) == -1 || (Helpers::returnSign($number) == -1 && !empty($mode));
142
    }
143
144
    /**
145
     * Avoid Scrutinizer problems concerning complexity.
146
     *
147
     * @return float|string
148
     */
149 20
    private static function argumentsOk(float $number, float $significance)
150
    {
151 20
        if ($significance == 0.0) {
152 1
            return Functions::DIV0();
153
        }
154 19
        if ($number == 0.0) {
155 3
            return 0.0;
156
        }
157 16
        if (Helpers::returnSign($significance) == 1) {
158 14
            return floor($number / $significance) * $significance;
159
        }
160 2
        if (Helpers::returnSign($number) == -1 && Helpers::returnSign($significance) == -1) {
161 1
            return floor($number / $significance) * $significance;
162
        }
163
164 1
        return Functions::NAN();
165
    }
166
}
167