2 * Copyright (c) 2017 Pantheon Technologies 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;
11 import static org.junit.jupiter.api.Assertions.assertEquals;
12 import static org.junit.jupiter.api.Assertions.assertFalse;
13 import static org.junit.jupiter.api.Assertions.assertThrows;
14 import static org.junit.jupiter.api.Assertions.assertTrue;
16 import java.math.BigDecimal;
17 import java.math.RoundingMode;
18 import org.junit.jupiter.api.Test;
20 public class Decimal64Test {
22 public void testParseEmpty() {
23 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf(""));
27 public void testParseSingleIllegal() {
28 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf("a"));
32 public void testParseSingleHighIllegal() {
33 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf(":"));
37 public void testParseZeroIllegal() {
38 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf("0a"));
42 public void testParseZeroHighIllegal() {
43 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf("0:"));
47 public void testParseZeroPointIllegal() {
48 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf("0.a"));
52 public void testParseZeroPointHighIllegal() {
53 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf("0.:"));
57 public void testParsePointIllegal() {
58 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf(".a"));
62 public void testParseMinus() {
63 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf("-"));
67 public void testParsePlus() {
68 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf("+"));
72 public void testParsePeriod() {
73 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf("."));
77 public void testParseTwoPeriods() {
78 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf(".."));
82 public void testParseTrailingPeriod() {
83 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf("0."));
87 public void testParseMultiplePeriods() {
88 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf("0.1."));
92 public void testParseLongString() {
93 Decimal64.valueOf("123456789012345678");
97 public void testParseLongDecimal() {
98 Decimal64.valueOf("0.12345678901234568");
102 public void testFractionLimits() {
103 Decimal64.valueOf("922337203685477580.7");
104 Decimal64.valueOf("9.223372036854775807");
106 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf("922337203685477580.71"));
107 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf("9.2233720368547758071"));
111 public void testParseTooLongString() {
112 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf("1234567890123456789"));
116 public void testParseTooLongDecimal() {
117 assertThrows(NumberFormatException.class, () -> Decimal64.valueOf("0.1234567890123456789"));
121 public void testParse() {
122 assertParsedVariants("0", 0, 0, 1);
123 assertParsedVariants("0.00", 0, 0, 1);
124 assertParsedVariants("00.0", 0, 0, 1);
125 assertParsedVariants("000.0", 0, 0, 1);
126 assertCanonicalVariants("10.0", 10, 0, 1);
127 assertCanonicalVariants("10.09", 10, 9, 2);
128 assertParsedVariants("10.0900900", 10, 9009, 5);
129 assertParsedVariants("0002210.09", 2210, 9, 2);
131 Decimal64 parsed = assertParsedString("0.0", 0, 0, 1, false);
132 parsed = assertParsedString("+0.0", 0, 0, 1, false);
133 assertEquals("0.0", parsed.toString());
134 assertEquals("0.0", parsed.toString());
135 parsed = assertParsedString("-0.0", 0, 0, 1, true);
136 assertEquals("0.0", parsed.toString());
138 assertCanonicalVariants("1.0", 1, 0, 1);
139 assertCanonicalVariants("2.3", 2, 3, 1);
143 public void testCompare() {
144 final Decimal64 one = Decimal64.valueOf("1");
145 final Decimal64 two = Decimal64.valueOf("2");
146 final Decimal64 three = Decimal64.valueOf("3");
147 final Decimal64 negOne = Decimal64.valueOf("-1");
148 final Decimal64 anotherOne = Decimal64.valueOf("1");
150 assertEquals(0, one.compareTo(one));
151 assertEquals(0, one.compareTo(anotherOne));
152 assertEquals(-1, one.compareTo(two));
153 assertEquals(-1, one.compareTo(three));
154 assertEquals(1, one.compareTo(negOne));
156 assertEquals(1, two.compareTo(one));
157 assertEquals(1, two.compareTo(anotherOne));
158 assertEquals(-1, two.compareTo(three));
159 assertEquals(1, one.compareTo(negOne));
163 public void testEquals() {
164 final Decimal64 one = Decimal64.valueOf("1");
165 final Decimal64 two = Decimal64.valueOf("2");
166 final Decimal64 anotherOne = Decimal64.valueOf("1");
168 assertTrue(one.equals(one));
169 assertTrue(one.equals(anotherOne));
170 assertFalse(one.equals(two));
171 assertTrue(two.equals(two));
172 assertFalse(two.equals(one));
174 assertFalse(one.equals(new Object()));
178 public void testConversions() {
179 assertEquals(new BigDecimal("0.12"), Decimal64.valueOf("0.12").decimalValue());
180 assertEquals(new BigDecimal("-0.12"), Decimal64.valueOf("-0.12").decimalValue());
181 assertEquals(new BigDecimal("0.12"), Decimal64.valueOf("+0.12").decimalValue());
182 assertEquals(new BigDecimal("123.456"), Decimal64.valueOf("123.456").decimalValue());
183 assertEquals(new BigDecimal("-123.456"), Decimal64.valueOf("-123.456").decimalValue());
185 assertEquals(0.12, Decimal64.valueOf("0.12").doubleValue(), 0);
186 assertEquals(-0.12, Decimal64.valueOf("-0.12").doubleValue(), 0);
188 assertEquals((float) 0.12, Decimal64.valueOf("0.12").floatValue(), 0);
189 assertEquals((float) -0.12, Decimal64.valueOf("-0.12").floatValue(), 0);
191 assertEquals(12345678901L, Decimal64.valueOf("12345678901").longValue());
192 assertEquals(-12345678901L, Decimal64.valueOf("-12345678901").longValue());
196 public void testFactories() {
197 assertEquals("0.0", Decimal64.valueOf(1, (byte) 0).toString());
198 assertEquals("1.0", Decimal64.valueOf(1, (byte) 1).toString());
199 assertEquals("-1.0", Decimal64.valueOf(1, (byte) -1).toString());
201 assertEquals("0.0", Decimal64.valueOf(1, (short) 0).toString());
202 assertEquals("1.0", Decimal64.valueOf(1, (short) 1).toString());
203 assertEquals("-1.0", Decimal64.valueOf(1, (short) -1).toString());
205 assertEquals("0.0", Decimal64.valueOf(1, 0).toString());
206 assertEquals("1.0", Decimal64.valueOf(1, 1).toString());
207 assertEquals("-1.0", Decimal64.valueOf(1, -1).toString());
209 assertEquals("0.0", Decimal64.valueOf(1, 0L).toString());
210 assertEquals("1.0", Decimal64.valueOf(1, 1L).toString());
211 assertEquals("-1.0", Decimal64.valueOf(1, -1L).toString());
213 assertEquals("0.0", Decimal64.valueOf(0.0F, RoundingMode.UNNECESSARY).toString());
214 assertEquals("1.0", Decimal64.valueOf(1.0F, RoundingMode.UNNECESSARY).toString());
215 assertEquals("-1.0", Decimal64.valueOf(-1.0F, RoundingMode.UNNECESSARY).toString());
217 assertEquals("0.0", Decimal64.valueOf(0.0D, RoundingMode.UNNECESSARY).toString());
218 assertEquals("1.0", Decimal64.valueOf(1.0D, RoundingMode.UNNECESSARY).toString());
219 assertEquals("-1.0", Decimal64.valueOf(-1.0D, RoundingMode.UNNECESSARY).toString());
221 assertEquals("0.0", Decimal64.valueOf(BigDecimal.ZERO).toString());
222 assertEquals("1.0", Decimal64.valueOf(BigDecimal.ONE).toString());
223 assertEquals("-1.0", Decimal64.valueOf(BigDecimal.ONE.negate()).toString());
227 public void testLeadingZeroToString() {
228 assertEquals("-0.63", Decimal64.valueOf("-0.63").toString());
232 public void testFractionPartToString() {
233 assertEquals("0.3", Decimal64.valueOf("0.3").toString());
234 assertEquals("0.03", Decimal64.valueOf("0.03").toString());
235 assertEquals("0.003", Decimal64.valueOf("0.003").toString());
236 assertEquals("-0.3", Decimal64.valueOf("-0.3").toString());
237 assertEquals("-0.03", Decimal64.valueOf("-0.03").toString());
238 assertEquals("-0.003", Decimal64.valueOf("-0.003").toString());
242 public void testScalingToString() {
243 assertEquals("30.0", Decimal64.of(1, 300).toString());
244 assertEquals("3.0", Decimal64.of(2, 300).toString());
245 assertEquals("0.3", Decimal64.of(3, 300).toString());
246 assertEquals("0.03", Decimal64.of(4, 300).toString());
250 public void testBoundaries() {
251 assertEquals(-128L, Decimal64.valueOf(1, Byte.MIN_VALUE).longValue());
252 assertEquals(127L, Decimal64.valueOf(1, Byte.MAX_VALUE).longValue());
253 assertEquals(-32768L, Decimal64.valueOf(2, Short.MIN_VALUE).longValue());
254 assertEquals(32767L, Decimal64.valueOf(2, Short.MAX_VALUE).longValue());
255 assertEquals(-2147483648L, Decimal64.valueOf(3, Integer.MIN_VALUE).longValue());
256 assertEquals(2147483647L, Decimal64.valueOf(3, Integer.MAX_VALUE).longValue());
260 public void testByteValueExact() {
261 assertEquals(Byte.MIN_VALUE, Decimal64.valueOf(1, Byte.MIN_VALUE).byteValueExact());
262 assertEquals(Byte.MAX_VALUE, Decimal64.valueOf(1, Byte.MAX_VALUE).byteValueExact());
266 public void testByteValueExactFrac() {
267 final Decimal64 dec = Decimal64.valueOf("1.1");
268 assertThrows(ArithmeticException.class, () -> dec.byteValueExact());
272 public void testByteValueExactRange() {
273 final Decimal64 dec = Decimal64.valueOf(1, Byte.MAX_VALUE + 1);
274 assertThrows(ArithmeticException.class, () -> dec.byteValueExact());
278 public void testShortValueExact() {
279 assertEquals(Short.MIN_VALUE, Decimal64.valueOf(1, Short.MIN_VALUE).shortValueExact());
280 assertEquals(Short.MAX_VALUE, Decimal64.valueOf(1, Short.MAX_VALUE).shortValueExact());
284 public void testShortValueExactFrac() {
285 final Decimal64 dec = Decimal64.valueOf("1.1");
286 assertThrows(ArithmeticException.class, () -> dec.shortValueExact());
290 public void testShortValueExactRange() {
291 final Decimal64 dec = Decimal64.valueOf(1, Short.MAX_VALUE + 1);
292 assertThrows(ArithmeticException.class, () -> dec.shortValueExact());
296 public void testIntValueExact() {
297 assertEquals(Integer.MIN_VALUE, Decimal64.valueOf(1, Integer.MIN_VALUE).intValueExact());
298 assertEquals(Integer.MAX_VALUE, Decimal64.valueOf(1, Integer.MAX_VALUE).intValueExact());
302 public void testIntValueExactFrac() {
303 final Decimal64 dec = Decimal64.valueOf("1.1");
304 assertThrows(ArithmeticException.class, () -> dec.intValueExact());
308 public void testIntValueExactRange() {
309 final Decimal64 dec = Decimal64.valueOf(1, Integer.MAX_VALUE + 1L);
310 assertThrows(ArithmeticException.class, () -> dec.intValueExact());
314 public void testLongValueExactFrac() {
315 final Decimal64 dec = Decimal64.valueOf("1.1");
316 assertThrows(ArithmeticException.class, () -> dec.longValueExact());
320 public void testLongValueOfBits() {
321 final Decimal64 dec = Decimal64.valueOf(2, 25552555555L);
322 assertEquals(2, dec.scale());
323 assertEquals(2555255555500L, dec.unscaledValue());
327 public void testLongValueOfNegativeBits() {
328 final Decimal64 dec = Decimal64.valueOf(2, -25552555555L);
329 assertEquals(2, dec.scale());
330 assertEquals(-2555255555500L, dec.unscaledValue());
334 public void testByteRange() {
335 for (int i = 1; i <= 16; ++i) {
336 assertEquals(Byte.MIN_VALUE, Decimal64.valueOf(i, Byte.MIN_VALUE).byteValueExact());
337 assertEquals(Byte.MAX_VALUE, Decimal64.valueOf(i, Byte.MAX_VALUE).byteValueExact());
339 for (int i = 17; i <= 18; ++i) {
341 assertThrows(IllegalArgumentException.class, () -> Decimal64.valueOf(scale, Byte.MIN_VALUE));
342 assertThrows(IllegalArgumentException.class, () -> Decimal64.valueOf(scale, Byte.MAX_VALUE));
347 public void testShortRange() {
348 for (int i = 1; i <= 14; ++i) {
349 assertEquals(Short.MIN_VALUE, Decimal64.valueOf(i, Short.MIN_VALUE).shortValueExact());
350 assertEquals(Short.MAX_VALUE, Decimal64.valueOf(i, Short.MAX_VALUE).shortValueExact());
352 for (int i = 15; i <= 18; ++i) {
354 assertThrows(IllegalArgumentException.class, () -> Decimal64.valueOf(scale, Short.MIN_VALUE));
355 assertThrows(IllegalArgumentException.class, () -> Decimal64.valueOf(scale, Short.MAX_VALUE));
360 public void testIntRange() {
361 for (int i = 1; i <= 9; ++i) {
362 assertEquals(Integer.MIN_VALUE, Decimal64.valueOf(i, Integer.MIN_VALUE).intValueExact());
363 assertEquals(Integer.MAX_VALUE, Decimal64.valueOf(i, Integer.MAX_VALUE).intValueExact());
365 for (int i = 10; i <= 18; ++i) {
367 assertThrows(IllegalArgumentException.class, () -> Decimal64.valueOf(scale, Integer.MIN_VALUE));
368 assertThrows(IllegalArgumentException.class, () -> Decimal64.valueOf(scale, Integer.MAX_VALUE));
373 public void testLongRange() {
374 for (int i = 1; i <= 18; ++i) {
376 assertThrows(IllegalArgumentException.class, () -> Decimal64.valueOf(scale, Long.MIN_VALUE));
377 assertThrows(IllegalArgumentException.class, () -> Decimal64.valueOf(scale, Long.MAX_VALUE));
381 private static void assertCanonicalVariants(final String str, final long intPart, final long fracPart,
383 assertCanonicalString(str, intPart, fracPart, digits, false);
384 assertCanonicalString("-" + str, intPart, fracPart, digits, true);
386 final Decimal64 parsed = assertParsedString("+" + str, intPart, fracPart, digits, false);
387 assertEquals(str, parsed.toString());
390 private static void assertParsedVariants(final String str, final long intPart, final long fracPart,
392 assertParsedString(str, intPart, fracPart, digits, false);
393 assertParsedString("-" + str, intPart, fracPart, digits, true);
394 assertParsedString("+" + str, intPart, fracPart, digits, false);
397 private static void assertCanonicalString(final String str, final long intPart, final long fracPart,
398 final int digits, final boolean negative) {
399 final Decimal64 parsed = assertParsedString(str, intPart, fracPart, digits, negative);
400 assertEquals(str, parsed.toString());
403 private static Decimal64 assertParsedString(final String str, final long intPart, final long fracPart,
404 final int digits, final boolean negative) {
405 final Decimal64 parsed = Decimal64.valueOf(str);
406 assertEquals(new Decimal64((byte) digits, intPart, fracPart, negative), parsed);