Skip to content

Commit 8d2bba9

Browse files
committed
Add overflow handling to toDecimal method
1 parent 262a623 commit 8d2bba9

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

src/main/java/org/firebirdsql/decimal/Decimal.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,35 @@ public final <D extends Decimal<D>> D toDecimal(Class<D> decimalType) {
136136
}
137137
}
138138

139+
/**
140+
* Converts this decimal to the requested decimal type, rounding when necessary.
141+
*
142+
* @param decimalType
143+
* Target decimal type
144+
* @param overflowHandling
145+
* Handling of overflows
146+
* @param <D>
147+
* Type parameter of decimal
148+
* @return This value after conversion, or this if {@code decimalType} is the same as this type
149+
* @throws IllegalArgumentException
150+
* If conversion to {@code decimalType} is not supported
151+
* @throws DecimalOverflowException
152+
* If {@code OverflowHandling#THROW_EXCEPTION} and the value is out of range for the target decimal type.
153+
*/
154+
public final <D extends Decimal<D>> D toDecimal(Class<D> decimalType, OverflowHandling overflowHandling) {
155+
if (decimalType == getClass()) {
156+
return decimalType.cast(this);
157+
} else if (decimalType == Decimal128.class) {
158+
return decimalType.cast(Decimal128.valueOf(this, OverflowHandling.THROW_EXCEPTION));
159+
} else if (decimalType == Decimal64.class) {
160+
return decimalType.cast(Decimal64.valueOf(this, OverflowHandling.THROW_EXCEPTION));
161+
} else if (decimalType == Decimal32.class) {
162+
return decimalType.cast(Decimal32.valueOf(this, OverflowHandling.THROW_EXCEPTION));
163+
} else {
164+
throw new IllegalArgumentException("Unsupported conversion to " + decimalType.getName());
165+
}
166+
}
167+
139168
final DecimalType getType() {
140169
return type;
141170
}

src/test/java/org/firebirdsql/decimal/Decimal128Test.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,13 +245,45 @@ public void toDecimal_Decimal128_Decimal32() {
245245
assertEquals(Decimal32.valueOf("1.23456"), value.toDecimal(Decimal32.class));
246246
}
247247

248+
@Test
249+
public void toDecimal_Decimal128_Decimal32_valueOutOfRange_toInfinity() {
250+
Decimal128 value = Decimal128.valueOf("1.23456E97");
251+
252+
assertSame(Decimal32.POSITIVE_INFINITY, value.toDecimal(Decimal32.class));
253+
}
254+
255+
@Test
256+
public void toDecimal_Decimal128_Decimal32_valueOutOfRange_throwException() {
257+
expectedException.expect(DecimalOverflowException.class);
258+
expectedException.expectMessage("The scale -92 is out of range for this type");
259+
Decimal128 value = Decimal128.valueOf("1.23456E97");
260+
261+
value.toDecimal(Decimal32.class, OverflowHandling.THROW_EXCEPTION);
262+
}
263+
248264
@Test
249265
public void toDecimal_Decimal128_Decimal64() {
250266
Decimal128 value = Decimal128.valueOf("1.23456");
251267

252268
assertEquals(Decimal64.valueOf("1.23456"), value.toDecimal(Decimal64.class));
253269
}
254270

271+
@Test
272+
public void toDecimal_Decimal128_Decimal64_valueOutOfRange_toInfinity() {
273+
Decimal128 value = Decimal128.valueOf("1.23456E385");
274+
275+
assertSame(Decimal32.POSITIVE_INFINITY, value.toDecimal(Decimal32.class));
276+
}
277+
278+
@Test
279+
public void toDecimal_Decimal128_Decimal64_valueOutOfRange_throwException() {
280+
expectedException.expect(DecimalOverflowException.class);
281+
expectedException.expectMessage("The scale -380 is out of range for this type");
282+
Decimal128 value = Decimal128.valueOf("1.23456E385");
283+
284+
value.toDecimal(Decimal32.class, OverflowHandling.THROW_EXCEPTION);
285+
}
286+
255287
@Test
256288
public void validateConstant_POSITIVE_ZERO() {
257289
assertEquals(BigDecimal.ZERO, POSITIVE_ZERO.toBigDecimal());

src/test/java/org/firebirdsql/decimal/Decimal64Test.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,22 @@ public void toDecimal_Decimal64_Decimal32() {
253253
assertEquals(Decimal32.valueOf("1.23456"), value.toDecimal(Decimal32.class));
254254
}
255255

256+
@Test
257+
public void toDecimal_Decimal64_Decimal32_valueOutOfRange_toInfinity() {
258+
Decimal64 value = Decimal64.valueOf("1.23456E97");
259+
260+
assertSame(Decimal32.POSITIVE_INFINITY, value.toDecimal(Decimal32.class));
261+
}
262+
263+
@Test
264+
public void toDecimal_Decimal64_Decimal32_valueOutOfRange_throwException() {
265+
expectedException.expect(DecimalOverflowException.class);
266+
expectedException.expectMessage("The scale -92 is out of range for this type");
267+
Decimal64 value = Decimal64.valueOf("1.23456E97");
268+
269+
value.toDecimal(Decimal32.class, OverflowHandling.THROW_EXCEPTION);
270+
}
271+
256272
@Test
257273
public void toDecimal_Decimal64_Decimal128() {
258274
Decimal64 value = Decimal64.valueOf("1.23456");

0 commit comments

Comments
 (0)