1<?php
2
3declare(strict_types=1);
4
5namespace Brick\Math;
6
7/**
8 * Specifies a rounding behavior for numerical operations capable of discarding precision.
9 *
10 * Each rounding mode indicates how the least significant returned digit of a rounded result
11 * is to be calculated. If fewer digits are returned than the digits needed to represent the
12 * exact numerical result, the discarded digits will be referred to as the discarded fraction
13 * regardless the digits' contribution to the value of the number. In other words, considered
14 * as a numerical value, the discarded fraction could have an absolute value greater than one.
15 */
16final class RoundingMode
17{
18    /**
19     * Private constructor. This class is not instantiable.
20     *
21     * @codeCoverageIgnore
22     */
23    private function __construct()
24    {
25    }
26
27    /**
28     * Asserts that the requested operation has an exact result, hence no rounding is necessary.
29     *
30     * If this rounding mode is specified on an operation that yields a result that
31     * cannot be represented at the requested scale, a RoundingNecessaryException is thrown.
32     */
33    public const UNNECESSARY = 0;
34
35    /**
36     * Rounds away from zero.
37     *
38     * Always increments the digit prior to a nonzero discarded fraction.
39     * Note that this rounding mode never decreases the magnitude of the calculated value.
40     */
41    public const UP = 1;
42
43    /**
44     * Rounds towards zero.
45     *
46     * Never increments the digit prior to a discarded fraction (i.e., truncates).
47     * Note that this rounding mode never increases the magnitude of the calculated value.
48     */
49    public const DOWN = 2;
50
51    /**
52     * Rounds towards positive infinity.
53     *
54     * If the result is positive, behaves as for UP; if negative, behaves as for DOWN.
55     * Note that this rounding mode never decreases the calculated value.
56     */
57    public const CEILING = 3;
58
59    /**
60     * Rounds towards negative infinity.
61     *
62     * If the result is positive, behave as for DOWN; if negative, behave as for UP.
63     * Note that this rounding mode never increases the calculated value.
64     */
65    public const FLOOR = 4;
66
67    /**
68     * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.
69     *
70     * Behaves as for UP if the discarded fraction is >= 0.5; otherwise, behaves as for DOWN.
71     * Note that this is the rounding mode commonly taught at school.
72     */
73    public const HALF_UP = 5;
74
75    /**
76     * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round down.
77     *
78     * Behaves as for UP if the discarded fraction is > 0.5; otherwise, behaves as for DOWN.
79     */
80    public const HALF_DOWN = 6;
81
82    /**
83     * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards positive infinity.
84     *
85     * If the result is positive, behaves as for HALF_UP; if negative, behaves as for HALF_DOWN.
86     */
87    public const HALF_CEILING = 7;
88
89    /**
90     * Rounds towards "nearest neighbor" unless both neighbors are equidistant, in which case round towards negative infinity.
91     *
92     * If the result is positive, behaves as for HALF_DOWN; if negative, behaves as for HALF_UP.
93     */
94    public const HALF_FLOOR = 8;
95
96    /**
97     * Rounds towards the "nearest neighbor" unless both neighbors are equidistant, in which case rounds towards the even neighbor.
98     *
99     * Behaves as for HALF_UP if the digit to the left of the discarded fraction is odd;
100     * behaves as for HALF_DOWN if it's even.
101     *
102     * Note that this is the rounding mode that statistically minimizes
103     * cumulative error when applied repeatedly over a sequence of calculations.
104     * It is sometimes known as "Banker's rounding", and is chiefly used in the USA.
105     */
106    public const HALF_EVEN = 9;
107}
108