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

Ceiling::floorCheck1Arg()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 2
rs 10
c 1
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 Ceiling
9
{
10
    /**
11
     * CEILING.
12
     *
13
     * Returns number rounded up, away from zero, to the nearest multiple of significance.
14
     *        For example, if you want to avoid using pennies in your prices and your product is
15
     *        priced at $4.42, use the formula =CEILING(4.42,0.05) to round prices up to the
16
     *        nearest nickel.
17
     *
18
     * Excel Function:
19
     *        CEILING(number[,significance])
20
     *
21
     * @param float $number the number you want the ceiling
22
     * @param float $significance the multiple to which you want to round
23
     *
24
     * @return float|string Rounded Number, or a string containing an error
25
     */
26 34
    public static function ceiling($number, $significance = null)
27
    {
28 34
        if ($significance === null) {
29 5
            self::floorCheck1Arg();
30
        }
31
32
        try {
33 31
            $number = Helpers::validateNumericNullBool($number);
34 29
            $significance = Helpers::validateNumericNullSubstitution($significance, ($number < 0) ? -1 : 1);
35 3
        } catch (Exception $e) {
36 3
            return $e->getMessage();
37
        }
38
39 28
        return self::argumentsOk((float) $number, (float) $significance);
40
    }
41
42
    /**
43
     * CEILING.MATH.
44
     *
45
     * Round a number down to the nearest integer or to the nearest multiple of significance.
46
     *
47
     * Excel Function:
48
     *        CEILING.MATH(number[,significance[,mode]])
49
     *
50
     * @param mixed $number Number to round
51
     * @param mixed $significance Significance
52
     * @param int $mode direction to round negative numbers
53
     *
54
     * @return float|string Rounded Number, or a string containing an error
55
     */
56 27
    public static function math($number, $significance = null, $mode = 0)
57
    {
58
        try {
59 27
            $number = Helpers::validateNumericNullBool($number);
60 25
            $significance = Helpers::validateNumericNullSubstitution($significance, ($number < 0) ? -1 : 1);
61 25
            $mode = Helpers::validateNumericNullSubstitution($mode, null);
62 2
        } catch (Exception $e) {
63 2
            return $e->getMessage();
64
        }
65
66 25
        if (empty($significance * $number)) {
67 5
            return 0.0;
68
        }
69 20
        if (self::ceilingMathTest((float) $significance, (float) $number, (int) $mode)) {
70 6
            return floor($number / $significance) * $significance;
71
        }
72
73 14
        return ceil($number / $significance) * $significance;
74
    }
75
76
    /**
77
     * CEILING.PRECISE.
78
     *
79
     * Rounds number up, away from zero, to the nearest multiple of significance.
80
     *
81
     * Excel Function:
82
     *        CEILING.PRECISE(number[,significance])
83
     *
84
     * @param mixed $number the number you want to round
85
     * @param float $significance the multiple to which you want to round
86
     *
87
     * @return float|string Rounded Number, or a string containing an error
88
     */
89 21
    public static function precise($number, $significance = 1)
90
    {
91
        try {
92 21
            $number = Helpers::validateNumericNullBool($number);
93 19
            $significance = Helpers::validateNumericNullSubstitution($significance, null);
94 3
        } catch (Exception $e) {
95 3
            return $e->getMessage();
96
        }
97
98 18
        if (!$significance) {
99 1
            return 0.0;
100
        }
101 17
        $result = $number / abs($significance);
102
103 17
        return ceil($result) * $significance * (($significance < 0) ? -1 : 1);
104
    }
105
106
    /**
107
     * Let CEILINGMATH complexity pass Scrutinizer.
108
     */
109 20
    private static function ceilingMathTest(float $significance, float $number, int $mode): bool
110
    {
111 20
        return ((float) $significance < 0) || ((float) $number < 0 && !empty($mode));
112
    }
113
114
    /**
115
     * Avoid Scrutinizer problems concerning complexity.
116
     *
117
     * @return float|string
118
     */
119 28
    private static function argumentsOk(float $number, float $significance)
120
    {
121 28
        if (empty($number * $significance)) {
122 3
            return 0.0;
123
        }
124 25
        if (Helpers::returnSign($number) == Helpers::returnSign($significance)) {
125 22
            return ceil($number / $significance) * $significance;
126
        }
127
128 3
        return Functions::NAN();
129
    }
130
131 5
    private static function floorCheck1Arg(): void
132
    {
133 5
        $compatibility = Functions::getCompatibilityMode();
134 5
        if ($compatibility === Functions::COMPATIBILITY_EXCEL) {
135 3
            throw new Exception('Excel requires 2 arguments for CEILING');
136
        }
137 2
    }
138
}
139