Skip to content

Commit 2390708

Browse files
committed
optimize deserialize float
1 parent 0e44f76 commit 2390708

File tree

5 files changed

+34
-51
lines changed

5 files changed

+34
-51
lines changed

core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF16.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -2631,7 +2631,7 @@ public double readDoubleValue() {
26312631
value = false;
26322632
}
26332633
if (!value) {
2634-
if (scale > -128 && scale < 128) {
2634+
if (scale > 0 && scale < 128) {
26352635
doubleValue = TypeUtils.doubleValue(fc == '-' ? -1 : 1, Math.abs(result), scale);
26362636
} else {
26372637
result = 1; // invalid
@@ -2803,7 +2803,7 @@ public float readFloatValue() {
28032803
value = false;
28042804
}
28052805
if (!value) {
2806-
if (scale > -128 && scale < 128) {
2806+
if (scale > 0 && scale < 128) {
28072807
floatValue = TypeUtils.floatValue(fc == '-' ? -1 : 1, Math.abs(result), scale);
28082808
} else {
28092809
result = 1; // invalid

core/src/main/java/com/alibaba/fastjson2/JSONReaderUTF8.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -3692,7 +3692,7 @@ public final double readDoubleValue() {
36923692
value = false;
36933693
}
36943694
if (!value) {
3695-
if (scale > -128 && scale < 128) {
3695+
if (scale > 0 && scale < 128) {
36963696
doubleValue = TypeUtils.doubleValue(fc == '-' ? -1 : 1, Math.abs(result), scale);
36973697
} else {
36983698
result = 1; // invalid
@@ -3864,7 +3864,7 @@ public final float readFloatValue() {
38643864
value = false;
38653865
}
38663866
if (!value) {
3867-
if (scale > -128 && scale < 128) {
3867+
if (scale > 0 && scale < 128) {
38683868
floatValue = TypeUtils.floatValue(fc == '-' ? -1 : 1, Math.abs(result), scale);
38693869
} else {
38703870
result = 1; // invalid

core/src/main/java/com/alibaba/fastjson2/util/MutableBigInteger.java

+4-9
Original file line numberDiff line numberDiff line change
@@ -599,15 +599,6 @@ private int divadd(int[] a, int[] result, int offset) {
599599
return (int) carry;
600600
}
601601

602-
private long toLong() {
603-
assert (intLen <= 2) : "this MutableBigInteger exceeds the range of long";
604-
if (intLen == 0) {
605-
return 0;
606-
}
607-
long d = value[offset] & LONG_MASK;
608-
return (intLen == 2) ? d << 32 | (value[offset + 1] & LONG_MASK) : d;
609-
}
610-
611602
public long longValue(int sign) {
612603
if (intLen == 0 || sign == 0) {
613604
return 0;
@@ -621,6 +612,10 @@ public long longValue(int sign) {
621612
return result;
622613
}
623614

615+
public int intValue() {
616+
return value[value.length - 1];
617+
}
618+
624619
private int[] getMagnitudeArray() {
625620
if (offset > 0 || value.length != intLen) {
626621
// Shrink value to be the total magnitude

core/src/main/java/com/alibaba/fastjson2/util/TypeUtils.java

+25-37
Original file line numberDiff line numberDiff line change
@@ -3686,7 +3686,6 @@ public static boolean validateIPv6(String str) {
36863686
return colonCount > 0 && colonCount < 8;
36873687
}
36883688

3689-
private static final BigInteger[] BIG_TEN_POWERS_TABLE;
36903689
private static final int[][] BIG_TEN_POWERS_MAGIC_TABLE = {
36913690
{1},
36923691
{10},
@@ -3818,23 +3817,6 @@ public static boolean validateIPv6(String str) {
38183817
{59, 391113267, -1868644376, -112737054, -1389121638, 2073349066, -799507145, -404191822, -422998195, -1210336922, -2147483648, 0, 0, 0}
38193818
};
38203819

3821-
static {
3822-
BigInteger[] bigInts = new BigInteger[128];
3823-
bigInts[0] = BigInteger.ONE;
3824-
bigInts[1] = BigInteger.TEN;
3825-
long longValue = 10;
3826-
for (int i = 2; i < 19; ++i) {
3827-
longValue *= 10;
3828-
bigInts[i] = BigInteger.valueOf(longValue);
3829-
}
3830-
BigInteger bigInt = bigInts[18];
3831-
for (int i = 19; i < 128; ++i) {
3832-
bigInt = bigInt.multiply(BigInteger.TEN);
3833-
bigInts[i] = bigInt;
3834-
}
3835-
BIG_TEN_POWERS_TABLE = bigInts;
3836-
}
3837-
38383820
private static long divideAndRemainder(int[] m, int[] n) {
38393821
MutableBigInteger q = new MutableBigInteger(),
38403822
a = new MutableBigInteger(m),
@@ -3843,6 +3825,14 @@ private static long divideAndRemainder(int[] m, int[] n) {
38433825
return q.longValue(1);
38443826
}
38453827

3828+
private static int divideAndRemainderInt(int[] m, int[] n) {
3829+
MutableBigInteger q = new MutableBigInteger(),
3830+
a = new MutableBigInteger(m),
3831+
b = new MutableBigInteger(n);
3832+
a.divideKnuth(b, q, false);
3833+
return q.intValue();
3834+
}
3835+
38463836
private static int[] shiftLeft(int[] mag, int n) {
38473837
int nInts = n >>> 5;
38483838
int nBits = n & 0x1f;
@@ -3886,11 +3876,6 @@ public static double doubleValue(int signNum, long intCompact, int scale) {
38863876
return signNum * Double.POSITIVE_INFINITY;
38873877
}
38883878

3889-
if (scale < 0) {
3890-
BigInteger pow10 = BIG_TEN_POWERS_TABLE[-scale];
3891-
BigInteger w = BigInteger.valueOf(intCompact);
3892-
return signNum * w.multiply(pow10).doubleValue();
3893-
}
38943879
if (scale == 0) {
38953880
return signNum * (double) intCompact;
38963881
}
@@ -3939,25 +3924,28 @@ public static float floatValue(int signNum, long intCompact, int scale) {
39393924
if (qb > Q_MAX_F + P_F + 1) { // qb > 129
39403925
return signNum * Float.POSITIVE_INFINITY;
39413926
}
3942-
if (scale < 0) {
3943-
BigInteger w = BigInteger.valueOf(intCompact);
3944-
return signNum * w.multiply(BIG_TEN_POWERS_TABLE[-scale]).floatValue();
3927+
if (scale == 0) {
3928+
return signNum * (float) intCompact;
39453929
}
39463930

3947-
BigInteger w = BigInteger.valueOf(intCompact);
3948-
int ql = (int) qb - (P_F + 3);
3949-
BigInteger pow10 = BIG_TEN_POWERS_TABLE[scale];
3950-
BigInteger m, n;
3931+
int[] magic_w = new int[]{
3932+
(int) (intCompact >>> 32),
3933+
(int) intCompact
3934+
};
3935+
int[] magic_m, magic_n;
3936+
int ql = (int) qb - (P_F + 3); // narrowing qb to an int is safe
3937+
int[] pow10 = BIG_TEN_POWERS_MAGIC_TABLE[scale];
39513938
if (ql <= 0) {
3952-
m = w.shiftLeft(-ql);
3953-
n = pow10;
3939+
magic_m = shiftLeft(magic_w, -ql);
3940+
magic_n = pow10.clone();
39543941
} else {
3955-
m = w;
3956-
n = pow10.shiftLeft(ql);
3942+
magic_m = magic_w;
3943+
magic_n = shiftLeft(pow10, ql);
39573944
}
3958-
BigInteger[] qr = m.divideAndRemainder(n);
3959-
int i = qr[0].intValue();
3960-
int sb = qr[1].signum();
3945+
3946+
int i = divideAndRemainderInt(magic_m, magic_n);
3947+
3948+
int sb = intCompact == 0 ? 0 : 1;
39613949
int dq = (Integer.SIZE - (P_F + 2)) - Integer.numberOfLeadingZeros(i);
39623950
int eq = (Q_MIN_F - 2) - ql;
39633951
if (dq >= eq) {

core/src/test/java/com/alibaba/fastjson2/JSONReaderFloatTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ public void test15() {
170170
String str0 = new String(chars, 0, OFF + 3);
171171
float f0 = Float.parseFloat(str0);
172172
double d0 = Double.parseDouble(str0);
173-
assertEquals(f0, JSON.parseObject(str0, Float.class));
173+
assertEquals(f0, JSON.parseObject(str0, Float.class), str0);
174174
assertEquals(d0, JSON.parseObject(str0, Double.class));
175175
assertEquals(f0, ((BigDecimal) JSON.parse(str0, JSONReader.Feature.UseBigDecimalForFloats)).floatValue());
176176
assertEquals(d0, ((BigDecimal) JSON.parse(str0, JSONReader.Feature.UseBigDecimalForDoubles)).doubleValue());

0 commit comments

Comments
 (0)