summaryrefslogtreecommitdiff
path: root/deps/icu-small/source/i18n/number_roundingutils.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/icu-small/source/i18n/number_roundingutils.h')
-rw-r--r--deps/icu-small/source/i18n/number_roundingutils.h141
1 files changed, 141 insertions, 0 deletions
diff --git a/deps/icu-small/source/i18n/number_roundingutils.h b/deps/icu-small/source/i18n/number_roundingutils.h
new file mode 100644
index 0000000000..6868ee0b86
--- /dev/null
+++ b/deps/icu-small/source/i18n/number_roundingutils.h
@@ -0,0 +1,141 @@
+// © 2017 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING && !UPRV_INCOMPLETE_CPP11_SUPPORT
+#ifndef __NUMBER_ROUNDINGUTILS_H__
+#define __NUMBER_ROUNDINGUTILS_H__
+
+#include "number_types.h"
+
+U_NAMESPACE_BEGIN
+namespace number {
+namespace impl {
+namespace roundingutils {
+
+enum Section {
+ SECTION_LOWER_EDGE = -1,
+ SECTION_UPPER_EDGE = -2,
+ SECTION_LOWER = 1,
+ SECTION_MIDPOINT = 2,
+ SECTION_UPPER = 3
+};
+
+/**
+ * Converts a rounding mode and metadata about the quantity being rounded to a boolean determining
+ * whether the value should be rounded toward infinity or toward zero.
+ *
+ * <p>The parameters are of type int because benchmarks on an x86-64 processor against OpenJDK
+ * showed that ints were demonstrably faster than enums in switch statements.
+ *
+ * @param isEven Whether the digit immediately before the rounding magnitude is even.
+ * @param isNegative Whether the quantity is negative.
+ * @param section Whether the part of the quantity to the right of the rounding magnitude is
+ * exactly halfway between two digits, whether it is in the lower part (closer to zero), or
+ * whether it is in the upper part (closer to infinity). See {@link #SECTION_LOWER}, {@link
+ * #SECTION_MIDPOINT}, and {@link #SECTION_UPPER}.
+ * @param roundingMode The integer version of the {@link RoundingMode}, which you can get via
+ * {@link RoundingMode#ordinal}.
+ * @param status Error code, set to U_FORMAT_INEXACT_ERROR if the rounding mode is kRoundUnnecessary.
+ * @return true if the number should be rounded toward zero; false if it should be rounded toward
+ * infinity.
+ */
+inline bool
+getRoundingDirection(bool isEven, bool isNegative, Section section, RoundingMode roundingMode,
+ UErrorCode &status) {
+ switch (roundingMode) {
+ case RoundingMode::UNUM_ROUND_UP:
+ // round away from zero
+ return false;
+
+ case RoundingMode::UNUM_ROUND_DOWN:
+ // round toward zero
+ return true;
+
+ case RoundingMode::UNUM_ROUND_CEILING:
+ // round toward positive infinity
+ return isNegative;
+
+ case RoundingMode::UNUM_ROUND_FLOOR:
+ // round toward negative infinity
+ return !isNegative;
+
+ case RoundingMode::UNUM_ROUND_HALFUP:
+ switch (section) {
+ case SECTION_MIDPOINT:
+ return false;
+ case SECTION_LOWER:
+ return true;
+ case SECTION_UPPER:
+ return false;
+ default:
+ break;
+ }
+ break;
+
+ case RoundingMode::UNUM_ROUND_HALFDOWN:
+ switch (section) {
+ case SECTION_MIDPOINT:
+ return true;
+ case SECTION_LOWER:
+ return true;
+ case SECTION_UPPER:
+ return false;
+ default:
+ break;
+ }
+ break;
+
+ case RoundingMode::UNUM_ROUND_HALFEVEN:
+ switch (section) {
+ case SECTION_MIDPOINT:
+ return isEven;
+ case SECTION_LOWER:
+ return true;
+ case SECTION_UPPER:
+ return false;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ status = U_FORMAT_INEXACT_ERROR;
+ return false;
+}
+
+/**
+ * Gets whether the given rounding mode's rounding boundary is at the midpoint. The rounding
+ * boundary is the point at which a number switches from being rounded down to being rounded up.
+ * For example, with rounding mode HALF_EVEN, HALF_UP, or HALF_DOWN, the rounding boundary is at
+ * the midpoint, and this function would return true. However, for UP, DOWN, CEILING, and FLOOR,
+ * the rounding boundary is at the "edge", and this function would return false.
+ *
+ * @param roundingMode The integer version of the {@link RoundingMode}.
+ * @return true if rounding mode is HALF_EVEN, HALF_UP, or HALF_DOWN; false otherwise.
+ */
+inline bool roundsAtMidpoint(int roundingMode) {
+ switch (roundingMode) {
+ case RoundingMode::UNUM_ROUND_UP:
+ case RoundingMode::UNUM_ROUND_DOWN:
+ case RoundingMode::UNUM_ROUND_CEILING:
+ case RoundingMode::UNUM_ROUND_FLOOR:
+ return false;
+
+ default:
+ return true;
+ }
+}
+
+} // namespace roundingutils
+} // namespace impl
+} // namespace number
+U_NAMESPACE_END
+
+#endif //__NUMBER_ROUNDINGUTILS_H__
+
+#endif /* #if !UCONFIG_NO_FORMATTING */