Skip to content

Commit

Permalink
refactor: 优化数字计算逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
zhou-hao committed Aug 1, 2024
1 parent e4a3d9a commit 6e20b0e
Show file tree
Hide file tree
Showing 9 changed files with 329 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.jetlinks.reactor.ql.feature.FilterFeature;
import org.jetlinks.reactor.ql.feature.ValueMapFeature;
import org.jetlinks.reactor.ql.utils.CastUtils;
import org.jetlinks.reactor.ql.utils.CompareUtils;
import org.reactivestreams.Publisher;
import reactor.core.publisher.Mono;

Expand Down Expand Up @@ -70,8 +71,8 @@ public static boolean predicate(Object val, Object between, Object and) {
return false;
}

return numberValue.doubleValue() >= numberBetween.doubleValue()
&& numberValue.doubleValue() <= numberAnd.doubleValue();
return CompareUtils.compare(numberValue, numberBetween) >= 0
&& CompareUtils.compare(numberValue, numberAnd) <= 0;
}

if (val == null || between == null || and == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public GreaterEqualsTanFilter(String type) {

@Override
protected boolean doTest(Number left, Number right) {
return left.doubleValue() >= right.doubleValue();
return CompareUtils.compare(left, right) >= 0;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public GreaterTanFilter(String type) {

@Override
protected boolean doTest(Number left, Number right) {
return left.doubleValue() > right.doubleValue();
return CompareUtils.compare(left, right) > 0;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public LessEqualsTanFilter(String type) {

@Override
protected boolean doTest(Number left, Number right) {
return left.doubleValue() <= right.doubleValue();
return CompareUtils.compare(left, right) <= 0;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public LessTanFilter(String type) {

@Override
protected boolean doTest(Number left, Number right) {
return left.doubleValue() < right.doubleValue();
return CompareUtils.compare(left, right) < 0;
}

@Override
Expand Down
175 changes: 117 additions & 58 deletions src/main/java/org/jetlinks/reactor/ql/utils/CalculateUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,105 +2,164 @@

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.function.BiFunction;

public class CalculateUtils {

public static long bitAnd(Number left, Number right) {
return left.longValue() & right.longValue();
public static Number bitAnd(Number left, Number right) {
return calculate(left, right,
(l, r) -> l & r,
(l, r) -> l.longValue() & r.longValue(),
(l, r) -> l.toBigInteger().and(r.toBigInteger()),
BigInteger::and);
}

public static long bitOr(Number left, Number right) {
return left.longValue() | right.longValue();
public static Number bitOr(Number left, Number right) {
return calculate(left, right,
(l, r) -> l | r,
(l, r) -> l.longValue() | r.longValue(),
(l, r) -> l.toBigInteger().or(r.toBigInteger()),
BigInteger::or);
}

public static long bitMutex(Number left, Number right) {
return left.longValue() ^ right.longValue();
public static Number bitMutex(Number left, Number right) {
return calculate(left, right,
(l, r) -> l ^ r,
(l, r) -> l.longValue() ^ r.longValue(),
(l, r) -> l.toBigInteger().xor(r.toBigInteger()),
BigInteger::xor);
}

public static long bitCount(Number left) {
return Long.bitCount(left.longValue());
public static int bitCount(Number left) {
return CalculateUtils
.calculate(
left, left,
(l, r) -> Long.bitCount(l),
(l, r) -> Long.bitCount(l.longValue()),
(l, r) -> l.toBigInteger().bitCount(),
(l, r) -> l.bitCount());
}

public static long leftShift(Number left, Number right) {
return left.longValue() << right.longValue();
public static Number leftShift(Number left, Number right) {
return CalculateUtils
.calculate(
left, right,
(l, r) -> l << r,
(l, r) -> l.longValue() << r.longValue(),
(l, r) -> l.toBigInteger().shiftLeft(r.intValue()),
(l, r) -> l.shiftLeft(r.intValue()));
}

public static long unsignedRightShift(Number left, Number right) {
return left.longValue() >>> right.longValue();
}

public static long rightShift(Number left, Number right) {
return left.longValue() >> right.longValue();
public static Number rightShift(Number left, Number right) {
return CalculateUtils
.calculate(
left, right,
(l, r) -> l >> r,
(l, r) -> l.longValue() >> r.longValue(),
(l, r) -> l.toBigInteger().shiftRight(r.intValue()),
(l, r) -> l.shiftRight(r.intValue()));
}

public static long bitNot(Number left) {
return ~left.longValue();
public static Number bitNot(Number left) {
return calculate(left, left,
(l, r) -> ~l,
(l, r) -> ~l.longValue(),
(l, r) -> l.toBigInteger().not(),
(l, r) -> l.not());
}

public static Number mod(Number left, Number right) {
if (left instanceof Double
|| left instanceof Float) {
return left.doubleValue() % right.doubleValue();
}

if (left instanceof BigDecimal && right instanceof BigDecimal) {
return ((BigDecimal) left).remainder(((BigDecimal) right));
}

return left.longValue() % right.longValue();
return calculate(left, right,
(l, r) -> l % r,
(l, r) -> l % r,
BigDecimal::remainder,
BigInteger::remainder);
}

public static Number division(Number left, Number right) {
if (left instanceof Double
|| left instanceof Float) {
return left.doubleValue() / right.doubleValue();
}

if (left instanceof BigDecimal && right instanceof BigDecimal) {
return ((BigDecimal) left).divide(((BigDecimal) right), RoundingMode.HALF_UP);
}

return left.longValue() / right.longValue();
return calculate(left, right,
(l, r) -> l / r,
(l, r) -> l / r,
BigDecimal::divide,
BigInteger::divide);
}

public static Number multiply(Number left, Number right) {
if (left instanceof Double
|| left instanceof Float) {
return left.doubleValue() * right.doubleValue();
}
return calculate(left, right,
(l, r) -> l * r,
(l, r) -> l * r,
BigDecimal::multiply,
BigInteger::multiply);
}

if (left instanceof BigDecimal && right instanceof BigDecimal) {
return ((BigDecimal) left).multiply(((BigDecimal) right));
}
public static Number add(Number left, Number right) {
return calculate(left, right,
Long::sum,
Double::sum,
BigDecimal::add,
BigInteger::add);
}

return left.longValue() * right.longValue();
public static Number subtract(Number left, Number right) {
return calculate(left, right,
(l, r) -> l - r,
(l, r) -> l - r,
BigDecimal::subtract,
BigInteger::subtract);
}

public static Number add(Number left, Number right) {
if (left instanceof Double
|| left instanceof Float) {
return left.doubleValue() + right.doubleValue();
public static <T> T calculate(Number left,
Number right,
BiFunction<Long, Long, T> opsForLong,
BiFunction<Double, Double, T> opsForDouble,
BiFunction<BigDecimal, BigDecimal, T> opsForDecimal,
BiFunction<BigInteger, BigInteger, T> opsForInteger) {
if (left instanceof BigDecimal) {
return calculate((BigDecimal) left, right, opsForDecimal);
}

if (left instanceof BigDecimal && right instanceof BigDecimal) {
return ((BigDecimal) left).add(((BigDecimal) right));
if (right instanceof BigDecimal) {
return calculate((BigDecimal) right, left, (r, l) -> opsForDecimal.apply(l, r));
}

return left.longValue() + right.longValue();
if (left instanceof BigInteger) {
return calculate((BigInteger) left, right, opsForInteger);
}
if (right instanceof BigInteger) {
return calculate((BigInteger) right, left, (r, l) -> opsForInteger.apply(l, r));
}
if (left instanceof Float || right instanceof Float ||
left instanceof Double || right instanceof Double) {
return opsForDouble.apply(left.doubleValue(), right.doubleValue());
}
return opsForLong.apply(left.longValue(), right.longValue());
}

public static Number subtract(Number left, Number right) {
if (left instanceof Double
|| left instanceof Float) {
return left.doubleValue() - right.doubleValue();
public static <T> T calculate(BigDecimal left, Number right,
BiFunction<BigDecimal, BigDecimal, T> ops) {
if (right instanceof BigDecimal) {
return ops.apply(left, ((BigDecimal) right));
}

if (left instanceof BigDecimal && right instanceof BigDecimal) {
return ((BigDecimal) left).subtract(((BigDecimal) right));
if (right instanceof BigInteger) {
return ops.apply(left, new BigDecimal((BigInteger) right));
}
return ops.apply(left, BigDecimal.valueOf(right.doubleValue()));
}

return left.longValue() - right.longValue();
public static <T> T calculate(BigInteger left, Number right,
BiFunction<BigInteger, BigInteger, T> ops) {
if (right instanceof BigInteger) {
return ops.apply(left, ((BigInteger) right));
}
if (right instanceof BigDecimal) {
return ops.apply(left, ((BigDecimal) right).toBigInteger());
}
return ops.apply(left, BigInteger.valueOf(right.longValue()));
}


}
59 changes: 56 additions & 3 deletions src/main/java/org/jetlinks/reactor/ql/utils/CompareUtils.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.jetlinks.reactor.ql.utils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.*;
import java.util.Date;
import java.util.Objects;
Expand Down Expand Up @@ -46,10 +48,14 @@ public static int compare(Object source, Object target) {
target = Date.from(((LocalDate) target).atStartOfDay(ZoneId.systemDefault()).toInstant());
}
if (source instanceof LocalTime) {
source = Date.from((LocalDateTime.of(LocalDate.now(), ((LocalTime) source))).atZone(ZoneId.systemDefault()).toInstant());
source = Date.from((LocalDateTime.of(LocalDate.now(), ((LocalTime) source)))
.atZone(ZoneId.systemDefault())
.toInstant());
}
if (target instanceof LocalTime) {
target = Date.from((LocalDateTime.of(LocalDate.now(), ((LocalTime) target))).atZone(ZoneId.systemDefault()).toInstant());
target = Date.from((LocalDateTime.of(LocalDate.now(), ((LocalTime) target)))
.atZone(ZoneId.systemDefault())
.toInstant());
}

if (source instanceof Date) {
Expand Down Expand Up @@ -107,7 +113,54 @@ public static boolean equals(Object source, Object target) {
}

private static int compare(Number number, Object target) {
return Double.compare(number.doubleValue(), CastUtils.castNumber(target).doubleValue());
return compare(number, CastUtils.castNumber(target, (ignore) -> null));
}

private static int compare(BigDecimal number, Number target) {
if (target instanceof BigDecimal) {
return number.compareTo(((BigDecimal) target));
} else if (target instanceof BigInteger) {
return number.compareTo(new BigDecimal(((BigInteger) target)));
} else {
return number.compareTo(BigDecimal.valueOf(target.doubleValue()));
}
}

private static int compare(BigInteger number, Number target) {
if (target instanceof BigDecimal) {
return number.compareTo(((BigDecimal) target).toBigInteger());
} else if (target instanceof BigInteger) {
return number.compareTo(((BigInteger) target));
} else {
return number.compareTo(BigInteger.valueOf(target.longValue()));
}
}

public static int compare(Number number, Number target) {
if (number == null && target == null) {
return 0;
}
if (number != null && target == null) {
return 1;
}
if (number == null) {
return -1;
}
if (number instanceof BigDecimal) {
return compare((BigDecimal) number, target);
}
if (target instanceof BigDecimal) {
return -compare((BigDecimal) target, number);
}

if (number instanceof BigInteger) {
return compare((BigInteger) number, target);
}
if (target instanceof BigInteger) {
return -compare((BigInteger) target, number);
}

return Double.compare(number.doubleValue(), target.doubleValue());
}

private static int compare(Enum<?> e, Object target) {
Expand Down
Loading

0 comments on commit 6e20b0e

Please sign in to comment.