Skip to content

Commit 871ddc1

Browse files
authored
Merge pull request #323 from alex268/master
Fix decimal INF, NEG_INF, NAN values
2 parents 7e303cb + 6735da1 commit 871ddc1

File tree

2 files changed

+69
-30
lines changed

2 files changed

+69
-30
lines changed

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

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,15 @@ public long getLow() {
6060
}
6161

6262
public boolean isInf() {
63-
return this == INF;
63+
return this.high == INF.high && this.low == INF.low;
6464
}
6565

6666
public boolean isNegativeInf() {
67-
return this == NEG_INF;
67+
return this.high == NEG_INF.high && this.low == NEG_INF.low;
6868
}
6969

7070
public boolean isNan() {
71-
return this == NAN;
71+
return this.high == NAN.high && this.low == NAN.low;
7272
}
7373

7474
public boolean isZero() {
@@ -273,19 +273,28 @@ private static long getLongBe(byte[] buf, int from, int to) {
273273
}
274274

275275
private static boolean isNan(long high, long low) {
276-
return NAN.getHigh() == high && NAN.getLow() == low;
276+
return NAN.high == high && NAN.low == low;
277277
}
278278

279279
private static boolean isInf(long high, long low) {
280-
return high > INF.getHigh() ||
281-
(high == INF.getHigh() && Long.compareUnsigned(low, INF.getLow()) >= 0);
280+
return high > INF.high || (high == INF.high && Long.compareUnsigned(low, INF.low) >= 0);
282281
}
283282

284283
private static boolean isNegInf(long high, long low) {
285-
return high < NEG_INF.getHigh() ||
286-
(high == NEG_INF.getHigh() && Long.compareUnsigned(low, NEG_INF.getLow()) <= 0);
284+
return high < NEG_INF.high || (high == NEG_INF.high && Long.compareUnsigned(low, NEG_INF.low) <= 0);
287285
}
288286

287+
private static DecimalValue newNan(DecimalType type) {
288+
return new DecimalValue(type, NAN.high, NAN.low);
289+
}
290+
291+
private static DecimalValue newInf(DecimalType type) {
292+
return new DecimalValue(type, INF.high, INF.low);
293+
}
294+
295+
private static DecimalValue newNegInf(DecimalType type) {
296+
return new DecimalValue(type, NEG_INF.high, NEG_INF.low);
297+
}
289298
static DecimalValue fromUnscaledLong(DecimalType type, long value) {
290299
if (value == 0) {
291300
return new DecimalValue(type, 0, 0);
@@ -300,15 +309,15 @@ static DecimalValue fromBits(DecimalType type, long high, long low) {
300309
}
301310

302311
if (isNan(high, low)) {
303-
return NAN;
312+
return newNan(type);
304313
}
305314

306315
if (isInf(high, low)) {
307-
return INF;
316+
return newInf(type);
308317
}
309318

310319
if (isNegInf(high, low)) {
311-
return NEG_INF;
320+
return newNegInf(type);
312321
}
313322

314323
return new DecimalValue(type, high, low);
@@ -322,7 +331,7 @@ static DecimalValue fromUnscaledBigInteger(DecimalType type, BigInteger value) {
322331

323332
boolean negative = value.signum() < 0;
324333
if (bitLength > 128) {
325-
return negative ? DecimalValue.NEG_INF : DecimalValue.INF;
334+
return negative ? newNegInf(type) : newInf(type);
326335
}
327336

328337
byte[] buf = value.abs().toByteArray();
@@ -358,7 +367,7 @@ private static DecimalValue fromUnsignedLong(DecimalType type, boolean positive,
358367
lowHi = lowHi & HALF_LONG_MASK;
359368
if ((high & LONG_SIGN_BIT) != 0) {
360369
// number is too big, return infinite
361-
return positive ? INF : NEG_INF;
370+
return positive ? newInf(type) : newNegInf(type);
362371
}
363372
}
364373

@@ -408,11 +417,11 @@ static DecimalValue fromString(DecimalType type, String value) {
408417
char c3 = value.charAt(cursor + 2);
409418

410419
if ((c1 == 'i' || c1 == 'I') && (c2 == 'n' || c2 == 'N') || (c3 == 'f' || c3 == 'F')) {
411-
return negative ? DecimalValue.NEG_INF : DecimalValue.INF;
420+
return negative ? newNegInf(type) : newInf(type);
412421
}
413422

414423
if ((c1 == 'n' || c1 == 'N') && (c2 == 'a' || c2 == 'A') || (c3 == 'n' || c3 == 'N')) {
415-
return DecimalValue.NAN;
424+
return new DecimalValue(type, NAN.high, NAN.low);
416425
}
417426
}
418427

table/src/test/java/tech/ydb/table/values/DecimalValueTest.java

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,22 @@ public void inf() {
8080
DecimalValue value = type.newValue(inf);
8181
Assert.assertTrue(value.isInf());
8282
Assert.assertFalse(value.isNegative());
83-
Assert.assertSame(DecimalValue.INF, value);
83+
Assert.assertEquals(DecimalValue.INF, value);
84+
inf = inf.add(k);
85+
}
86+
}
87+
88+
@Test
89+
public void infDefaulttype() {
90+
DecimalType type = DecimalType.getDefault();
91+
BigInteger inf = BigInteger.TEN.pow(DecimalType.MAX_PRECISION);
92+
BigInteger k = BigInteger.valueOf(0x10000000_00000000L);
93+
94+
for (int i = 0; i < 100; i++) {
95+
DecimalValue value = type.newValue(inf);
96+
Assert.assertTrue(value.isInf());
97+
Assert.assertFalse(value.isNegative());
98+
Assert.assertNotEquals(DecimalValue.INF, value);
8499
inf = inf.add(k);
85100
}
86101
}
@@ -95,7 +110,22 @@ public void negativeInf() {
95110
DecimalValue value = type.newValue(inf);
96111
Assert.assertTrue(value.isNegativeInf());
97112
Assert.assertTrue(value.isNegative());
98-
Assert.assertSame(DecimalValue.NEG_INF, value);
113+
Assert.assertEquals(DecimalValue.NEG_INF, value);
114+
inf = inf.subtract(k);
115+
}
116+
}
117+
118+
@Test
119+
public void negativeInfDefaultType() {
120+
DecimalType type = DecimalType.getDefault();
121+
BigInteger inf = BigInteger.TEN.negate().pow(DecimalType.MAX_PRECISION);
122+
BigInteger k = BigInteger.valueOf(0x10000000_00000000L);
123+
124+
for (int i = 0; i < 100; i++) {
125+
DecimalValue value = type.newValue(inf);
126+
Assert.assertTrue(value.isNegativeInf());
127+
Assert.assertTrue(value.isNegative());
128+
Assert.assertNotEquals(DecimalValue.NEG_INF, value);
99129
inf = inf.subtract(k);
100130
}
101131
}
@@ -126,19 +156,19 @@ public void zero() {
126156
public void ofString() {
127157
DecimalType t = DecimalType.getDefault();
128158

129-
Assert.assertSame(DecimalValue.INF, t.newValue("inf"));
130-
Assert.assertSame(DecimalValue.INF, t.newValue("Inf"));
131-
Assert.assertSame(DecimalValue.INF, t.newValue("INF"));
132-
Assert.assertSame(DecimalValue.INF, t.newValue("+inf"));
133-
Assert.assertSame(DecimalValue.INF, t.newValue("+Inf"));
134-
Assert.assertSame(DecimalValue.INF, t.newValue("+INF"));
135-
Assert.assertSame(DecimalValue.NEG_INF, t.newValue("-inf"));
136-
Assert.assertSame(DecimalValue.NEG_INF, t.newValue("-Inf"));
137-
Assert.assertSame(DecimalValue.NEG_INF, t.newValue("-INF"));
138-
Assert.assertSame(DecimalValue.NAN, t.newValue("nan"));
139-
Assert.assertSame(DecimalValue.NAN, t.newValue("Nan"));
140-
Assert.assertSame(DecimalValue.NAN, t.newValue("NaN"));
141-
Assert.assertSame(DecimalValue.NAN, t.newValue("NAN"));
159+
Assert.assertTrue(t.newValue("inf").isInf());
160+
Assert.assertTrue(t.newValue("Inf").isInf());
161+
Assert.assertTrue(t.newValue("INF").isInf());
162+
Assert.assertTrue(t.newValue("+inf").isInf());
163+
Assert.assertTrue(t.newValue("+Inf").isInf());
164+
Assert.assertTrue(t.newValue("+INF").isInf());
165+
Assert.assertTrue(t.newValue("-inf").isNegativeInf());
166+
Assert.assertTrue(t.newValue("-Inf").isNegativeInf());
167+
Assert.assertTrue(t.newValue("-INF").isNegativeInf());
168+
Assert.assertTrue(t.newValue("nan").isNan());
169+
Assert.assertTrue(t.newValue("Nan").isNan());
170+
Assert.assertTrue(t.newValue("NaN").isNan());
171+
Assert.assertTrue(t.newValue("NAN").isNan());
142172

143173
Assert.assertTrue(t.newValue("0").isZero());
144174
Assert.assertTrue(t.newValue("00").isZero());

0 commit comments

Comments
 (0)