2 * Copyright (c) 2022 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.common;
10 import static org.junit.jupiter.api.Assertions.assertEquals;
11 import static org.junit.jupiter.api.Assertions.assertSame;
12 import static org.junit.jupiter.api.Assertions.assertThrows;
14 import java.math.RoundingMode;
15 import org.junit.jupiter.api.Test;
17 public class YT1440Test {
19 public void testScaleSame() {
20 final var twenty = Decimal64.valueOf(2, 20);
21 assertSame(twenty, twenty.scaleTo(2));
23 // Do not tolerate null rounding even for no-op
24 assertThrows(NullPointerException.class, () -> twenty.scaleTo(2, null));
28 public void testScaleZero() {
29 final var two = Decimal64.valueOf(2, 0);
30 final var one = two.scaleTo(1);
31 assertEquals(1, one.scale());
32 assertEquals(0, one.unscaledValue());
33 final var three = two.scaleTo(3);
34 assertEquals(3, three.scale());
35 assertEquals(0, three.unscaledValue());
39 public void testScaleUpNoRemain() {
41 final var two = Decimal64.valueOf(2, 20);
44 final var five = two.scaleTo(5);
45 assertEquals(5, five.scale());
46 assertEquals(two, five);
47 assertEquals("20.0", five.toString());
50 final var ex = assertThrows(ArithmeticException.class, () -> two.scaleTo(18));
51 assertEquals("Increasing scale of 20.0 to 18 would overflow", ex.getMessage());
55 public void testScaleDownNoRemain() {
57 final var five = Decimal64.valueOf(5, 20);
60 final var two = five.scaleTo(2);
61 assertEquals(2, two.scale());
62 assertEquals(five, two);
63 assertEquals("20.0", two.toString());
67 public void testScaleDownPositive() {
68 final var two = Decimal64.valueOf("0.63");
69 assertEquals(2, two.scale());
70 assertEquals(63, two.unscaledValue());
73 assertScaleDown(7, two, 1, RoundingMode.UP);
74 assertScaleDown(6, two, 1, RoundingMode.DOWN);
75 assertScaleDown(7, two, 1, RoundingMode.CEILING);
76 assertScaleDown(6, two, 1, RoundingMode.FLOOR);
77 assertScaleDown(6, two, 1, RoundingMode.HALF_UP);
78 assertScaleDown(6, two, 1, RoundingMode.HALF_DOWN);
79 assertScaleDown(6, two, 1, RoundingMode.HALF_EVEN);
81 final var three = Decimal64.valueOf("0.635");
82 assertEquals(3, three.scale());
83 assertEquals(635, three.unscaledValue());
86 assertScaleDown(64, three, 2, RoundingMode.UP);
87 assertScaleDown(63, three, 2, RoundingMode.DOWN);
88 assertScaleDown(64, three, 2, RoundingMode.CEILING);
89 assertScaleDown(63, three, 2, RoundingMode.FLOOR);
90 assertScaleDown(64, three, 2, RoundingMode.HALF_UP);
91 assertScaleDown(63, three, 2, RoundingMode.HALF_DOWN);
92 assertScaleDown(64, three, 2, RoundingMode.HALF_EVEN);
95 assertScaleDown(7, three, 1, RoundingMode.UP);
96 assertScaleDown(6, three, 1, RoundingMode.DOWN);
97 assertScaleDown(7, three, 1, RoundingMode.CEILING);
98 assertScaleDown(6, three, 1, RoundingMode.FLOOR);
99 assertScaleDown(6, three, 1, RoundingMode.HALF_UP);
100 assertScaleDown(6, three, 1, RoundingMode.HALF_DOWN);
101 assertScaleDown(6, three, 1, RoundingMode.HALF_EVEN);
103 final var four = Decimal64.valueOf("0.6355");
104 assertEquals(4, four.scale());
105 assertEquals(6355, four.unscaledValue());
108 assertScaleDown(64, four, 2, RoundingMode.UP);
109 assertScaleDown(63, four, 2, RoundingMode.DOWN);
110 assertScaleDown(64, four, 2, RoundingMode.CEILING);
111 assertScaleDown(63, four, 2, RoundingMode.FLOOR);
112 assertScaleDown(64, four, 2, RoundingMode.HALF_UP);
113 assertScaleDown(64, four, 2, RoundingMode.HALF_DOWN);
114 assertScaleDown(64, four, 2, RoundingMode.HALF_EVEN);
116 final var five = Decimal64.valueOf("0.635").scaleTo(5);
117 assertEquals(5, five.scale());
118 assertEquals(63500, five.unscaledValue());
121 assertScaleDown(64, five, 2, RoundingMode.UP);
122 assertScaleDown(63, five, 2, RoundingMode.DOWN);
123 assertScaleDown(64, five, 2, RoundingMode.CEILING);
124 assertScaleDown(63, five, 2, RoundingMode.FLOOR);
125 assertScaleDown(64, five, 2, RoundingMode.HALF_UP);
126 assertScaleDown(63, five, 2, RoundingMode.HALF_DOWN);
127 assertScaleDown(64, five, 2, RoundingMode.HALF_EVEN);
131 public void testScaleDownNegative() {
132 final var two = Decimal64.valueOf("-0.63");
133 assertEquals(2, two.scale());
134 assertEquals(-63, two.unscaledValue());
137 assertScaleDown(-7, two, 1, RoundingMode.UP);
138 assertScaleDown(-6, two, 1, RoundingMode.DOWN);
139 assertScaleDown(-6, two, 1, RoundingMode.CEILING);
140 assertScaleDown(-7, two, 1, RoundingMode.FLOOR);
141 assertScaleDown(-6, two, 1, RoundingMode.HALF_UP);
142 assertScaleDown(-6, two, 1, RoundingMode.HALF_DOWN);
143 assertScaleDown(-6, two, 1, RoundingMode.HALF_EVEN);
145 final var three = Decimal64.valueOf("-0.635");
146 assertEquals(3, three.scale());
147 assertEquals(-635, three.unscaledValue());
150 assertScaleDown(-64, three, 2, RoundingMode.UP);
151 assertScaleDown(-63, three, 2, RoundingMode.DOWN);
152 assertScaleDown(-63, three, 2, RoundingMode.CEILING);
153 assertScaleDown(-64, three, 2, RoundingMode.FLOOR);
154 assertScaleDown(-64, three, 2, RoundingMode.HALF_UP);
155 assertScaleDown(-63, three, 2, RoundingMode.HALF_DOWN);
156 assertScaleDown(-64, three, 2, RoundingMode.HALF_EVEN);
159 assertScaleDown(-7, three, 1, RoundingMode.UP);
160 assertScaleDown(-6, three, 1, RoundingMode.DOWN);
161 assertScaleDown(-6, three, 1, RoundingMode.CEILING);
162 assertScaleDown(-7, three, 1, RoundingMode.FLOOR);
163 assertScaleDown(-6, three, 1, RoundingMode.HALF_UP);
164 assertScaleDown(-6, three, 1, RoundingMode.HALF_DOWN);
165 assertScaleDown(-6, three, 1, RoundingMode.HALF_EVEN);
167 final var four = Decimal64.valueOf("-0.6355");
168 assertEquals(4, four.scale());
169 assertEquals(-6355, four.unscaledValue());
172 assertScaleDown(-64, four, 2, RoundingMode.UP);
173 assertScaleDown(-63, four, 2, RoundingMode.DOWN);
174 assertScaleDown(-63, four, 2, RoundingMode.CEILING);
175 assertScaleDown(-64, four, 2, RoundingMode.FLOOR);
176 assertScaleDown(-64, four, 2, RoundingMode.HALF_UP);
177 assertScaleDown(-64, four, 2, RoundingMode.HALF_DOWN);
178 assertScaleDown(-64, four, 2, RoundingMode.HALF_EVEN);
180 final var five = Decimal64.valueOf("-0.635").scaleTo(5);
181 assertEquals(5, five.scale());
182 assertEquals(-63500, five.unscaledValue());
185 assertScaleDown(-64, five, 2, RoundingMode.UP);
186 assertScaleDown(-63, five, 2, RoundingMode.DOWN);
187 assertScaleDown(-63, five, 2, RoundingMode.CEILING);
188 assertScaleDown(-64, five, 2, RoundingMode.FLOOR);
189 assertScaleDown(-64, five, 2, RoundingMode.HALF_UP);
190 assertScaleDown(-63, five, 2, RoundingMode.HALF_DOWN);
191 assertScaleDown(-64, five, 2, RoundingMode.HALF_EVEN);
195 public void testScaleDownTrim() {
196 final var two = Decimal64.valueOf("0.63");
197 final var ex = assertThrows(ArithmeticException.class, () -> two.scaleTo(1));
198 assertEquals("Decreasing scale of 0.63 to 1 requires rounding", ex.getMessage());
201 private static void assertScaleDown(final long expectedUnscaled, final Decimal64 value, final int scale,
202 final RoundingMode mode) {
203 final var scaled = value.scaleTo(scale, mode);
204 assertEquals(scale, scaled.scale());
205 assertEquals(expectedUnscaled, scaled.unscaledValue());