}
public static Decimal64 valueOf(final int intVal) {
- return intVal < 0 ? new Decimal64(1, -intVal, 0, true) : new Decimal64(1, intVal, 0, false);
+ return intVal < 0 ? new Decimal64(1, - (long)intVal, 0, true) : new Decimal64(1, intVal, 0, false);
}
public static Decimal64 valueOf(final long longVal) {
return 1.0 * value / SCALE[scaleOffset];
}
+ /**
+ * Converts this {@code BigDecimal} to a {@code byte}, checking for lost information. If this {@code Decimal64} has
+ * a nonzero fractional part or is out of the possible range for a {@code byte} result then
+ * an {@code ArithmeticException} is thrown.
+ *
+ * @return this {@code Decimal64} converted to a {@code byte}.
+ * @throws ArithmeticException if {@code this} has a nonzero fractional part, or will not fit in a {@code byte}.
+ */
+ public byte byteValueExact() {
+ final long val = longValueExact();
+ final byte ret = (byte) val;
+ if (val != ret) {
+ throw new ArithmeticException("Value " + val + " is outside of byte range");
+ }
+ return ret;
+ }
+
+ /**
+ * Converts this {@code BigDecimal} to a {@code short}, checking for lost information. If this {@code Decimal64} has
+ * a nonzero fractional part or is out of the possible range for a {@code short} result then
+ * an {@code ArithmeticException} is thrown.
+ *
+ * @return this {@code Decimal64} converted to a {@code short}.
+ * @throws ArithmeticException if {@code this} has a nonzero fractional part, or will not fit in a {@code short}.
+ */
+ public short shortValueExact() {
+ final long val = longValueExact();
+ final short ret = (short) val;
+ if (val != ret) {
+ throw new ArithmeticException("Value " + val + " is outside of short range");
+ }
+ return ret;
+ }
+
+ /**
+ * Converts this {@code BigDecimal} to an {@code int}, checking for lost information. If this {@code Decimal64} has
+ * a nonzero fractional part or is out of the possible range for an {@code int} result then
+ * an {@code ArithmeticException} is thrown.
+ *
+ * @return this {@code Decimal64} converted to an {@code int}.
+ * @throws ArithmeticException if {@code this} has a nonzero fractional part, or will not fit in an {@code int}.
+ */
+ public int intValueExact() {
+ final long val = longValueExact();
+ final int ret = (int) val;
+ if (val != ret) {
+ throw new ArithmeticException("Value " + val + " is outside of integer range");
+ }
+ return ret;
+ }
+
+ /**
+ * Converts this {@code BigDecimal} to a {@code long}, checking for lost information. If this {@code Decimal64} has
+ * a nonzero fractional part then an {@code ArithmeticException} is thrown.
+ *
+ * @return this {@code Decimal64} converted to a {@code long}.
+ * @throws ArithmeticException if {@code this} has a nonzero fractional part.
+ */
+ public long longValueExact() {
+ if (fracPart() != 0) {
+ throw new ArithmeticException("Conversion of " + this + " would lose fraction");
+ }
+ return intPart();
+ }
+
@Override
@SuppressWarnings("checkstyle:parameterName")
public int compareTo(final Decimal64 o) {
assertEquals("-1.0", Decimal64.valueOf(BigDecimal.ONE.negate()).toString());
}
+ @Test
+ public void testBoundaries() {
+ assertEquals(-128L, Decimal64.valueOf(Byte.MIN_VALUE).longValue());
+ assertEquals(127L, Decimal64.valueOf(Byte.MAX_VALUE).longValue());
+ assertEquals(-32768L, Decimal64.valueOf(Short.MIN_VALUE).longValue());
+ assertEquals(32767L, Decimal64.valueOf(Short.MAX_VALUE).longValue());
+ assertEquals(-2147483648L, Decimal64.valueOf(Integer.MIN_VALUE).longValue());
+ assertEquals(2147483647L, Decimal64.valueOf(Integer.MAX_VALUE).longValue());
+ }
+
+ @Test
+ public void testByteValueExact() {
+ assertEquals(Byte.MIN_VALUE, Decimal64.valueOf(Byte.MIN_VALUE).byteValueExact());
+ assertEquals(Byte.MAX_VALUE, Decimal64.valueOf(Byte.MAX_VALUE).byteValueExact());
+ }
+
+ @Test(expected = ArithmeticException.class)
+ public void testByteValueExactFrac() {
+ Decimal64.valueOf("1.1").byteValueExact();
+ }
+
+ @Test(expected = ArithmeticException.class)
+ public void testByteValueExactRange() {
+ Decimal64.valueOf(Byte.MAX_VALUE + 1).byteValueExact();
+ }
+
+ @Test
+ public void testShortValueExact() {
+ assertEquals(Short.MIN_VALUE, Decimal64.valueOf(Short.MIN_VALUE).shortValueExact());
+ assertEquals(Short.MAX_VALUE, Decimal64.valueOf(Short.MAX_VALUE).shortValueExact());
+ }
+
+ @Test(expected = ArithmeticException.class)
+ public void testShortValueExactFrac() {
+ Decimal64.valueOf("1.1").shortValueExact();
+ }
+
+ @Test(expected = ArithmeticException.class)
+ public void testShortValueExactRange() {
+ Decimal64.valueOf(Short.MAX_VALUE + 1).shortValueExact();
+ }
+
+ @Test
+ public void testIntValueExact() {
+ assertEquals(Integer.MIN_VALUE, Decimal64.valueOf(Integer.MIN_VALUE).intValueExact());
+ assertEquals(Integer.MAX_VALUE, Decimal64.valueOf(Integer.MAX_VALUE).intValueExact());
+ }
+
+ @Test(expected = ArithmeticException.class)
+ public void testIntValueExactFrac() {
+ Decimal64.valueOf("1.1").intValueExact();
+ }
+
+ @Test(expected = ArithmeticException.class)
+ public void testIntValueExactRange() {
+ Decimal64.valueOf(Integer.MAX_VALUE + 1L).intValueExact();
+ }
+
+ @Test(expected = ArithmeticException.class)
+ public void testLongValueExactFrac() {
+ Decimal64.valueOf("1.1").longValueExact();
+ }
+
private static void assertCanonicalVariants(final String str, final long intPart, final long fracPart,
final int digits) {
assertCanonicalString(str, intPart, fracPart, digits, false);