package com.wis.leading.common.util;
import cn.hutool.core.util.NumberUtil;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;
@Slf4j
public final class Num {
private BigDecimal value;
private Num(BigDecimal value) {
this.value = value;
}
public static Num of(Number value) {
Objects.requireNonNull(value);
return new Num(NumberUtil.toBigDecimal(value));
}
public static Num of(Num value) {
return of(value.get());
}
public static Num of(String value) {
return of(new BigDecimal(value));
}
public static Num zero() {
return of(BigDecimal.ZERO);
}
public Num add(Number... toAdd) {
for (Number item : toAdd) {
value = NumberUtil.add(value, item);
}
return this;
}
public Num add(Num... toAdd) {
for (Num item : toAdd) {
value = NumberUtil.add(value, item.get());
}
return this;
}
public Num add(String... toAdd) {
for (String item : toAdd) {
value = NumberUtil.add(value, new BigDecimal(item));
}
return this;
}
public Num sub(Number... toSubtract) {
for (Number item : toSubtract) {
value = NumberUtil.sub(value, item);
}
return this;
}
public Num sub(Num... toSubtract) {
for (Num item : toSubtract) {
value = NumberUtil.sub(value, item.get());
}
return this;
}
public Num sub(String... toSubtract) {
for (String item : toSubtract) {
value = NumberUtil.sub(value, new BigDecimal(item));
}
return this;
}
public Num mul(Number... toMultiply) {
for (Number item : toMultiply) {
value = NumberUtil.mul(value, item);
}
return this;
}
public Num mul(Num... toMultiply) {
for (Num item : toMultiply) {
value = NumberUtil.mul(value, item.get());
}
return this;
}
public Num mul(String... toMultiply) {
for (String item : toMultiply) {
value = NumberUtil.mul(value, new BigDecimal(item));
}
return this;
}
public Num div(Number... toDivisor) {
for (Number item : toDivisor) {
value = NumberUtil.div(value, item);
}
return this;
}
public Num div(Num... toDivisor) {
for (Num item : toDivisor) {
value = NumberUtil.div(value, item.get());
}
return this;
}
public Num div(String... toDivisor) {
for (String item : toDivisor) {
value = NumberUtil.div(value, new BigDecimal(item));
}
return this;
}
public Num divSafe(Number... toDivisor) {
for (Number item : toDivisor) {
if (item == null || Num.of(item).isZero()) {
log.warn("安全除法检测到无效除数 - 当前值:{}, 除数:{} (除数为null或0,将返回0)", this.value, item);
value = BigDecimal.ZERO;
return this;
}
value = NumberUtil.div(value, item);
}
return this;
}
public Num divSafe(Num... toDivisor) {
for (Num item : toDivisor) {
if (item == null || item.isZero()) {
log.warn("安全除法检测到无效除数 - 当前值:{}, 除数:{} (除数为null或0,将返回0)", this.value, item);
value = BigDecimal.ZERO;
return this;
}
value = NumberUtil.div(value, item.get());
}
return this;
}
public Num divSafe(String... toDivisor) {
for (String item : toDivisor) {
if (item == null || Num.of(item).isZero()) {
log.warn("安全除法检测到无效除数 - 当前值:{}, 除数:'{}' (除数为null或0,将返回0)", this.value, item);
value = BigDecimal.ZERO;
return this;
}
value = NumberUtil.div(value, new BigDecimal(item));
}
return this;
}
public Num copy() {
return Num.of(this.value);
}
public BigDecimal get() {
return value;
}
public BigDecimal get(int newScale) {
return get().setScale(newScale, RoundingMode.HALF_UP);
}
public double getDoubleValue() {
return get().doubleValue();
}
public double getDoubleValue(int newScale) {
return get(newScale).doubleValue();
}
public boolean isZero() {
return compareTo(BigDecimal.ZERO) == 0;
}
public boolean gt(Number other) {
return compareTo(other) > 0;
}
public boolean gte(Number other) {
return compareTo(other) >= 0;
}
public boolean lt(Number other) {
return compareTo(other) < 0;
}
public boolean lte(Number other) {
return compareTo(other) <= 0;
}
public boolean eq(Number other) {
return compareTo(other) == 0;
}
public int compareTo(Number other) {
Objects.requireNonNull(other, "比较对象不能为null");
return value.compareTo(NumberUtil.toBigDecimal(other));
}
@Override
public String toString() {
return value.toPlainString();
}
}