Skip to content

Commit

Permalink
Add rounding mode for irrational BigDecimal numbers
Browse files Browse the repository at this point in the history
  • Loading branch information
volodya-lombrozo committed Mar 11, 2022
1 parent 13e98e2 commit bfa5698
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import com.clickhouse.client.ClickHouseChecker;
import com.clickhouse.client.ClickHouseValue;
import com.clickhouse.client.ClickHouseValues;
Expand All @@ -22,13 +24,15 @@ public static ClickHouseDoubleValue ofNull() {
}

/**
* Update given value to null or create a new instance if {@code ref} is null.
*
* Update given value to null or create a new instance if {@code ref} is
* null.
*
* @param ref object to update, could be null
* @return same object as {@code ref} or a new instance if it's null
*/
public static ClickHouseDoubleValue ofNull(ClickHouseValue ref) {
return ref instanceof ClickHouseDoubleValue ? ((ClickHouseDoubleValue) ref).set(true, 0D)
return ref instanceof ClickHouseDoubleValue ?
((ClickHouseDoubleValue) ref).set(true, 0D)
: new ClickHouseDoubleValue(true, 0D);
}

Expand All @@ -43,15 +47,17 @@ public static ClickHouseDoubleValue of(double value) {
}

/**
* Update value of the given object or create a new instance if {@code ref} is
* Update value of the given object or create a new instance if {@code
* ref} is
* null.
*
* @param ref object to update, could be null
* @param value value
* @return same object as {@code ref} or a new instance if it's null
*/
public static ClickHouseDoubleValue of(ClickHouseValue ref, double value) {
return ref instanceof ClickHouseDoubleValue ? ((ClickHouseDoubleValue) ref).set(false, value)
return ref instanceof ClickHouseDoubleValue ?
((ClickHouseDoubleValue) ref).set(false, value)
: new ClickHouseDoubleValue(false, value);
}

Expand Down Expand Up @@ -128,16 +134,16 @@ public BigDecimal asBigDecimal(int scale) {
if (isNull) {
return null;
}

final RoundingMode roundingMode = RoundingMode.HALF_UP;
BigDecimal dec = BigDecimal.valueOf(value);
if (value == 0D || isInfinity() || isNaN()) {
dec = dec.setScale(scale);
dec = dec.setScale(scale, roundingMode);
} else {
int diff = scale - dec.scale();
if (diff > 0) {
dec = dec.divide(BigDecimal.TEN.pow(diff + 1));
} else if (diff < 0) {
dec = dec.setScale(scale);
dec = dec.setScale(scale, roundingMode);
}
}
return dec;
Expand All @@ -156,7 +162,8 @@ public String asString(int length, Charset charset) {

String str = String.valueOf(value);
if (length > 0) {
ClickHouseChecker.notWithDifferentLength(str.getBytes(charset == null ? StandardCharsets.UTF_8 : charset),
ClickHouseChecker.notWithDifferentLength(str.getBytes(
charset == null ? StandardCharsets.UTF_8 : charset),
length);
}

Expand Down Expand Up @@ -225,27 +232,33 @@ public ClickHouseDoubleValue update(double value) {

@Override
public ClickHouseDoubleValue update(BigInteger value) {
return value == null ? resetToNullOrEmpty() : set(false, value.doubleValue());
return value
== null ? resetToNullOrEmpty() : set(false, value.doubleValue());
}

@Override
public ClickHouseDoubleValue update(BigDecimal value) {
return value == null ? resetToNullOrEmpty() : set(false, value.doubleValue());
return value
== null ? resetToNullOrEmpty() : set(false, value.doubleValue());
}

@Override
public ClickHouseDoubleValue update(Enum<?> value) {
return value == null ? resetToNullOrEmpty() : set(false, value.ordinal());
return value
== null ? resetToNullOrEmpty() : set(false, value.ordinal());
}

@Override
public ClickHouseDoubleValue update(String value) {
return value == null ? resetToNullOrEmpty() : set(false, Double.parseDouble(value));
return value
== null ? resetToNullOrEmpty() : set(false,
Double.parseDouble(value));
}

@Override
public ClickHouseDoubleValue update(ClickHouseValue value) {
return value == null ? resetToNullOrEmpty() : set(false, value.asDouble());
return value
== null ? resetToNullOrEmpty() : set(false, value.asDouble());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.time.LocalTime;
import java.time.ZoneOffset;
import java.util.Arrays;
import java.util.Collections;
import java.util.UUID;
import org.testng.annotations.Test;
import com.clickhouse.client.BaseClickHouseValueTest;
Expand Down Expand Up @@ -250,5 +251,38 @@ public void testValue() throws Exception {
buildMap(new Object[] { 1 }, new Double[] { -1D }), // typed Map
Arrays.asList(Double.valueOf(-1D)) // Tuple
);

checkValue(ClickHouseDoubleValue.of(4D/3), false, // isInfinity
false, // isNan
false, // isNull
true, // boolean
(byte) 1, // byte
(short) 1, // short
1, // int
1L, // long
1.3333334F, // float
1.3333333333333333D, // double
BigDecimal.valueOf(1L), // BigDecimal
BigDecimal.valueOf(1333,3), // BigDecimal
BigInteger.ONE, // BigInteger
ClickHouseDataType.values()[1].name(), // Enum<ClickHouseDataType>
1.3333333333333333D, // Object
LocalDate.ofEpochDay(1L), // Date
LocalDateTime.ofEpochSecond(1L, 0, ZoneOffset.UTC), // DateTime
LocalDateTime.ofEpochSecond(1L, 333333333, ZoneOffset.UTC), // DateTime(9)
Inet4Address.getAllByName("0.0.0.1")[0], // Inet4Address
Inet6Address.getAllByName("0:0:0:0:0:0:0:1")[0], // Inet6Address
"1.3333333333333333", // String
"1.3333333333333333", // SQL Expression
LocalTime.ofSecondOfDay(1), // Time
UUID.fromString("00000000-0000-0000-0000-000000000001"), // UUID
Object.class, // Key class
Double.class, // Value class
new Object[] { 1.3333333333333333D }, // Array
new Double[] { 1.3333333333333333D }, // typed Array
buildMap(new Object[] { 1 }, new Object[] { 1.3333333333333333D }), // Map
buildMap(new Object[] { 1 }, new Double[] { 1.3333333333333333D }), // typed Map
Collections.singletonList(1.3333333333333333D) // Tuple
);
}
}

0 comments on commit bfa5698

Please sign in to comment.