Skip to content

Commit cca97f3

Browse files
committed
Update DecimalType implementation, added +inf/-inf to every instance
1 parent 454f008 commit cca97f3

File tree

2 files changed

+54
-29
lines changed

2 files changed

+54
-29
lines changed

table/src/main/java/tech/ydb/table/values/DecimalType.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,17 @@ public class DecimalType implements Type {
1717
public static final int MAX_PRECISION = 35;
1818

1919
private static final InfValues[] INF_VALUES;
20-
2120
private static final DecimalType YDB_DEFAULT;
2221

2322
static {
23+
// Precalculate +inf/-inf values for all precisions
2424
INF_VALUES = new InfValues[DecimalType.MAX_PRECISION];
2525

2626
long mask32 = 0xFFFFFFFFL;
2727
long infHigh = 0;
28-
long infLow = 10;
28+
long infLow = 1;
2929

3030
for (int precision = 1; precision <= DecimalType.MAX_PRECISION; precision++) {
31-
INF_VALUES[precision - 1] = new InfValues(infHigh, infLow);
32-
3331
// multiply by 10
3432
long ll = 10 * (infLow & mask32);
3533
long lh = 10 * (infLow >>> 32) + (ll >>> 32);
@@ -38,6 +36,8 @@ public class DecimalType implements Type {
3836

3937
infLow = (lh << 32) + (ll & mask32);
4038
infHigh = (hh << 32) + (hl & mask32);
39+
40+
INF_VALUES[precision - 1] = new InfValues(infHigh, infLow);
4141
}
4242

4343
YDB_DEFAULT = DecimalType.of(22, 9);
@@ -47,10 +47,18 @@ public class DecimalType implements Type {
4747
private final int scale;
4848
private final InfValues inf;
4949

50+
private final DecimalValue infValue;
51+
private final DecimalValue negInfValue;
52+
private final DecimalValue nanValue;
53+
5054
private DecimalType(int precision, int scale) {
5155
this.precision = precision;
5256
this.scale = scale;
5357
this.inf = INF_VALUES[precision - 1];
58+
59+
this.infValue = new DecimalValue(this, DecimalValue.INF_HIGH, DecimalValue.INF_LOW);
60+
this.negInfValue = new DecimalValue(this, DecimalValue.NEG_INF_HIGH, DecimalValue.NEG_INF_LOW);
61+
this.nanValue = new DecimalValue(this, DecimalValue.NAN_HIGH, DecimalValue.NAN_LOW);
5462
}
5563

5664
public static DecimalType getDefault() {
@@ -82,6 +90,18 @@ public int getScale() {
8290
return scale;
8391
}
8492

93+
public DecimalValue getInf() {
94+
return infValue;
95+
}
96+
97+
public DecimalValue getNegInf() {
98+
return negInfValue;
99+
}
100+
101+
public DecimalValue getNaN() {
102+
return nanValue;
103+
}
104+
85105
@Override
86106
public boolean equals(Object o) {
87107
if (this == o) {

table/src/main/java/tech/ydb/table/values/DecimalValue.java

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,35 @@ public class DecimalValue implements Value<DecimalType> {
1818

1919
private static final BigInteger BIGINT_TWO = BigInteger.valueOf(2);
2020

21+
static final long INF_HIGH = 0x0013426172C74D82L;
22+
static final long INF_LOW = 0x2B878FE800000000L;
23+
static final long NEG_INF_HIGH = 0xFFECBD9E8D38B27DL;
24+
static final long NEG_INF_LOW = 0xD478701800000000L;
25+
static final long NAN_HIGH = 0x0013426172C74D82L;
26+
static final long NAN_LOW = 0x2B878FE800000001L;
27+
28+
2129
/**
30+
* @deprecated
2231
* Positive infinity 10^{@value DecimalType#MAX_PRECISION}.
2332
*/
33+
@Deprecated
2434
public static final DecimalValue INF = new DecimalValue(
2535
MAX_DECIMAL, 0x0013426172C74D82L, 0x2B878FE800000000L);
2636

2737
/**
28-
* Negative infinity -10^{@value DecimalType#MAX_PRECISION}.
38+
* @deprecated
39+
* Negative infinity -10^{@value DecimalType#MAX_PRECISI0ON}.
2940
*/
41+
@Deprecated
3042
public static final DecimalValue NEG_INF = new DecimalValue(
3143
MAX_DECIMAL, 0xFFECBD9E8D38B27DL, 0xD478701800000000L);
3244

3345
/**
46+
* @deprecated
3447
* Not a number 10^{@value DecimalType#MAX_PRECISION} + 1.
3548
*/
49+
@Deprecated
3650
public static final DecimalValue NAN = new DecimalValue(
3751
MAX_DECIMAL, 0x0013426172C74D82L, 0x2B878FE800000001L);
3852

@@ -60,15 +74,15 @@ public long getLow() {
6074
}
6175

6276
public boolean isInf() {
63-
return this.high == INF.high && this.low == INF.low;
77+
return this.high == INF_HIGH && this.low == INF_LOW;
6478
}
6579

6680
public boolean isNegativeInf() {
67-
return this.high == NEG_INF.high && this.low == NEG_INF.low;
81+
return this.high == NEG_INF_HIGH && this.low == NEG_INF_LOW;
6882
}
6983

7084
public boolean isNan() {
71-
return this.high == NAN.high && this.low == NAN.low;
85+
return this.high == NAN_HIGH && this.low == NAN_LOW;
7286
}
7387

7488
public boolean isZero() {
@@ -123,6 +137,9 @@ public BigDecimal toBigDecimal() {
123137
if (isZero()) {
124138
return BigDecimal.ZERO.setScale(type.getScale());
125139
}
140+
if (isInf() || isNegativeInf() || isNan()) {
141+
return new BigDecimal(toUnscaledBigInteger()).setScale(type.getScale());
142+
}
126143

127144
return new BigDecimal(toUnscaledBigInteger(), type.getScale());
128145
}
@@ -272,18 +289,6 @@ private static long getLongBe(byte[] buf, int from, int to) {
272289
return r;
273290
}
274291

275-
private static DecimalValue newNan(DecimalType type) {
276-
return new DecimalValue(type, NAN.high, NAN.low);
277-
}
278-
279-
private static DecimalValue newInf(DecimalType type) {
280-
return new DecimalValue(type, INF.high, INF.low);
281-
}
282-
283-
private static DecimalValue newNegInf(DecimalType type) {
284-
return new DecimalValue(type, NEG_INF.high, NEG_INF.low);
285-
}
286-
287292
private static boolean isNan(long high, long low) {
288293
return NAN.high == high && NAN.low == low;
289294
}
@@ -296,11 +301,11 @@ static DecimalValue fromUnscaledLong(DecimalType type, long low) {
296301
long high = low > 0 ? 0 : -1;
297302

298303
if (type.isInf(high, low)) {
299-
return newInf(type);
304+
return type.getInf();
300305
}
301306

302307
if (type.isNegInf(high, low)) {
303-
return newNegInf(type);
308+
return type.getNegInf();
304309
}
305310

306311
return new DecimalValue(type, high, low);
@@ -312,15 +317,15 @@ static DecimalValue fromBits(DecimalType type, long high, long low) {
312317
}
313318

314319
if (isNan(high, low)) {
315-
return newNan(type);
320+
return type.getNaN();
316321
}
317322

318323
if (type.isInf(high, low)) {
319-
return newInf(type);
324+
return type.getInf();
320325
}
321326

322327
if (type.isNegInf(high, low)) {
323-
return newNegInf(type);
328+
return type.getNegInf();
324329
}
325330

326331
return new DecimalValue(type, high, low);
@@ -334,7 +339,7 @@ static DecimalValue fromUnscaledBigInteger(DecimalType type, BigInteger value) {
334339

335340
boolean negative = value.signum() < 0;
336341
if (bitLength > 128) {
337-
return negative ? newNegInf(type) : newInf(type);
342+
return negative ? type.getNegInf() : type.getInf();
338343
}
339344

340345
byte[] buf = value.abs().toByteArray();
@@ -370,7 +375,7 @@ private static DecimalValue fromUnsignedLong(DecimalType type, boolean positive,
370375
lowHi = lowHi & HALF_LONG_MASK;
371376
if ((high & LONG_SIGN_BIT) != 0) {
372377
// number is too big, return infinite
373-
return positive ? newInf(type) : newNegInf(type);
378+
return positive ? type.getInf() : type.getNegInf();
374379
}
375380
}
376381

@@ -420,11 +425,11 @@ static DecimalValue fromString(DecimalType type, String value) {
420425
char c3 = value.charAt(cursor + 2);
421426

422427
if ((c1 == 'i' || c1 == 'I') && (c2 == 'n' || c2 == 'N') || (c3 == 'f' || c3 == 'F')) {
423-
return negative ? newNegInf(type) : newInf(type);
428+
return negative ? type.getNegInf() : type.getInf();
424429
}
425430

426431
if ((c1 == 'n' || c1 == 'N') && (c2 == 'a' || c2 == 'A') || (c3 == 'n' || c3 == 'N')) {
427-
return new DecimalValue(type, NAN.high, NAN.low);
432+
return type.getNaN();
428433
}
429434
}
430435

0 commit comments

Comments
 (0)