001/*
002 * The MIT License (MIT)
003 *
004 * Copyright (c) 2015-2023 decimal4j (tools4j), Marco Terzer
005 *
006 * Permission is hereby granted, free of charge, to any person obtaining a copy
007 * of this software and associated documentation files (the "Software"), to deal
008 * in the Software without restriction, including without limitation the rights
009 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
010 * copies of the Software, and to permit persons to whom the Software is
011 * furnished to do so, subject to the following conditions:
012 *
013 * The above copyright notice and this permission notice shall be included in all
014 * copies or substantial portions of the Software.
015 *
016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
017 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
018 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
019 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
020 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
021 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
022 * SOFTWARE.
023 */
024package org.decimal4j.truncate;
025
026
027/**
028 * Represents the truncated part for instance after division. It is passed to
029 * the rounding methods in {@link DecimalRounding}
030 */
031public enum TruncatedPart {
032        /**
033         * Truncated part {@code t == 0}.
034         */
035        ZERO {
036                @Override
037                public final boolean isGreaterThanZero() {
038                        return false;
039                }
040
041                @Override
042                public final boolean isEqualToHalf() {
043                        return false;
044                }
045
046                @Override
047                public final boolean isGreaterEqualHalf() {
048                        return false;
049                }
050
051                @Override
052                public final boolean isGreaterThanHalf() {
053                        return false;
054                }
055        },
056        /**
057         * Truncated part {@code 0 < t < 0.5}.
058         */
059        LESS_THAN_HALF_BUT_NOT_ZERO {
060                @Override
061                public final boolean isGreaterThanZero() {
062                        return true;
063                }
064
065                @Override
066                public final boolean isEqualToHalf() {
067                        return false;
068                }
069
070                @Override
071                public final boolean isGreaterEqualHalf() {
072                        return false;
073                }
074
075                @Override
076                public final boolean isGreaterThanHalf() {
077                        return false;
078                }
079        },
080        /**
081         * Truncated part {@code t == 0.5}.
082         */
083        EQUAL_TO_HALF {
084                @Override
085                public final boolean isGreaterThanZero() {
086                        return true;
087                }
088
089                @Override
090                public final boolean isEqualToHalf() {
091                        return true;
092                }
093
094                @Override
095                public final boolean isGreaterEqualHalf() {
096                        return true;
097                }
098
099                @Override
100                public final boolean isGreaterThanHalf() {
101                        return false;
102                }
103        },
104        /**
105         * Truncated part {@code t > 0.5}.
106         */
107        GREATER_THAN_HALF {
108                @Override
109                public final boolean isGreaterThanZero() {
110                        return true;
111                }
112
113                @Override
114                public final boolean isEqualToHalf() {
115                        return false;
116                }
117
118                @Override
119                public final boolean isGreaterEqualHalf() {
120                        return true;
121                }
122
123                @Override
124                public final boolean isGreaterThanHalf() {
125                        return true;
126                }
127        };
128
129        /**
130         * Returns true if the truncated part is greater than zero.
131         * 
132         * @return true if {@code this > 0}
133         */
134        abstract public boolean isGreaterThanZero();
135
136        /**
137         * Returns true if the truncated part is equal to one half.
138         * 
139         * @return true if {@code this == 0.5}
140         */
141        abstract public boolean isEqualToHalf();
142
143        /**
144         * Returns true if the truncated part is greater than or equal to one half.
145         * 
146         * @return true if {@code this >= 0.5}
147         */
148        abstract public boolean isGreaterEqualHalf();
149
150        /**
151         * Returns true if the truncated part is greater than one half.
152         * 
153         * @return true if {@code this > 0.5}
154         */
155        abstract public boolean isGreaterThanHalf();
156
157        /**
158         * Returns a truncated part constant given the first truncated digit and a
159         * boolean indicating whether there is non-zero digits after that.
160         * 
161         * @param firstTruncatedDigit
162         *            the first truncated digit, must be in {@code [0, 1, ..., 9]}
163         * @param zeroAfterFirstTruncatedDigit
164         *            true if all truncated digits after the first truncated digit
165         *            are zero, and false otherwise
166         * @return the truncated part constant equivalent to the given arguments
167         */
168        public static final TruncatedPart valueOf(int firstTruncatedDigit, boolean zeroAfterFirstTruncatedDigit) {
169                if (firstTruncatedDigit > 5) {
170                        return GREATER_THAN_HALF;
171                }
172                if (zeroAfterFirstTruncatedDigit) {
173                        if (firstTruncatedDigit == 5) {
174                                return EQUAL_TO_HALF;
175                        }
176                        if (firstTruncatedDigit > 0) {
177                                return LESS_THAN_HALF_BUT_NOT_ZERO;
178                        }
179                        return ZERO;
180                }
181                if (firstTruncatedDigit < 5) {
182                        return LESS_THAN_HALF_BUT_NOT_ZERO;
183                }
184                return GREATER_THAN_HALF;
185        }
186
187}