shz.core.NumberHelp Maven / Gradle / Ivy
package shz.core;
import shz.core.function.CharConsumer;
import shz.core.function.CharSequenceVisitor;
import shz.core.function.CharSupplier;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.DoubleAdder;
import java.util.concurrent.atomic.LongAdder;
public final class NumberHelp {
private NumberHelp() {
throw new IllegalStateException();
}
public static Byte getByte(Object obj) {
if (obj == null) return null;
if (obj instanceof Byte) return (Byte) obj;
if (obj instanceof Number) return ((Number) obj).byteValue();
if (obj instanceof CharSequence) try {
return Byte.parseByte(obj.toString());
} catch (NumberFormatException e) {
return null;
}
if (obj instanceof Boolean) return (byte) ((boolean) obj ? 1 : 0);
if (obj instanceof Character) {
int delta = (char) obj - '0';
return delta < 0 || delta > 9 ? null : (byte) delta;
}
return null;
}
public static Short getShort(Object obj) {
if (obj == null) return null;
if (obj instanceof Short) return (Short) obj;
if (obj instanceof Number) return ((Number) obj).shortValue();
if (obj instanceof CharSequence) try {
return Short.parseShort(obj.toString());
} catch (NumberFormatException e) {
return null;
}
if (obj instanceof Boolean) return (short) ((boolean) obj ? 1 : 0);
if (obj instanceof Character) {
int delta = (char) obj - '0';
return delta < 0 || delta > 9 ? null : (short) delta;
}
return null;
}
public static Integer getInteger(Object obj) {
if (obj == null) return null;
if (obj instanceof Integer) return (Integer) obj;
if (obj instanceof Number) return ((Number) obj).intValue();
if (obj instanceof CharSequence) try {
return Integer.parseInt(obj.toString());
} catch (NumberFormatException e) {
return null;
}
if (obj instanceof Boolean) return (boolean) obj ? 1 : 0;
if (obj instanceof Character) {
int delta = (char) obj - '0';
return delta < 0 || delta > 9 ? null : delta;
}
return null;
}
public static Long getLong(Object obj) {
if (obj == null) return null;
if (obj instanceof Long) return (Long) obj;
if (obj instanceof Number) return ((Number) obj).longValue();
if (obj instanceof CharSequence) try {
return Long.parseLong(obj.toString());
} catch (NumberFormatException e) {
return null;
}
if (obj instanceof Boolean) return (boolean) obj ? 1L : 0L;
if (obj instanceof Character) {
int delta = (char) obj - '0';
return delta < 0 || delta > 9 ? null : (long) delta;
}
return null;
}
public static Float getFloat(Object obj) {
if (obj == null) return null;
if (obj instanceof Float) return (Float) obj;
if (obj instanceof Number) return ((Number) obj).floatValue();
if (obj instanceof CharSequence) try {
return Float.parseFloat(obj.toString());
} catch (NumberFormatException e) {
return null;
}
if (obj instanceof Boolean) return (boolean) obj ? 1f : 0f;
if (obj instanceof Character) {
int delta = (char) obj - '0';
return delta < 0 || delta > 9 ? null : (float) delta;
}
return null;
}
public static Double getDouble(Object obj) {
if (obj == null) return null;
if (obj instanceof Double) return (Double) obj;
if (obj instanceof Number) return ((Number) obj).doubleValue();
if (obj instanceof CharSequence) try {
return Double.parseDouble(obj.toString());
} catch (NumberFormatException e) {
return null;
}
if (obj instanceof Boolean) return (boolean) obj ? 1D : 0D;
if (obj instanceof Character) {
int delta = (char) obj - '0';
return delta < 0 || delta > 9 ? null : (double) delta;
}
return null;
}
public static BigInteger getBigInteger(Object obj) {
if (obj == null) return null;
if (obj instanceof BigInteger) return (BigInteger) obj;
if (obj instanceof Number) return BigInteger.valueOf(((Number) obj).longValue());
if (obj instanceof CharSequence) try {
return new BigInteger(obj.toString());
} catch (NumberFormatException e) {
return null;
}
if (obj instanceof Boolean) return (boolean) obj ? BigInteger.ONE : BigInteger.ZERO;
if (obj instanceof Character) {
int delta = (char) obj - '0';
if (delta < 0 || delta > 9) return null;
return delta == 0 ? BigInteger.ZERO : delta == 1 ? BigInteger.ONE : BigInteger.valueOf(delta);
}
return null;
}
public static BigDecimal getBigDecimal(Object obj) {
if (obj == null) return null;
if (obj instanceof BigDecimal) return (BigDecimal) obj;
if (obj instanceof Number || obj instanceof CharSequence) try {
return new BigDecimal(obj.toString());
} catch (NumberFormatException e) {
return null;
}
if (obj instanceof Boolean) return (boolean) obj ? BigDecimal.ONE : BigDecimal.ZERO;
if (obj instanceof Character) {
int delta = (char) obj - '0';
if (delta < 0 || delta > 9) return null;
return delta == 0 ? BigDecimal.ZERO : delta == 1 ? BigDecimal.ONE : BigDecimal.valueOf(delta);
}
return null;
}
public static AtomicInteger getAtomicInteger(Object obj) {
if (obj == null) return null;
if (obj instanceof AtomicInteger) return (AtomicInteger) obj;
if (obj instanceof Number) return new AtomicInteger(((Number) obj).intValue());
if (obj instanceof CharSequence) try {
return new AtomicInteger(Integer.parseInt(obj.toString()));
} catch (NumberFormatException e) {
return null;
}
if (obj instanceof Boolean) return (boolean) obj ? new AtomicInteger(1) : new AtomicInteger();
if (obj instanceof Character) {
int delta = (char) obj - '0';
return delta < 0 || delta > 9 ? null : new AtomicInteger(delta);
}
return null;
}
public static AtomicLong getAtomicLong(Object obj) {
if (obj == null) return null;
if (obj instanceof AtomicLong) return (AtomicLong) obj;
if (obj instanceof Number) return new AtomicLong(((Number) obj).longValue());
if (obj instanceof CharSequence) try {
return new AtomicLong(Long.parseLong(obj.toString()));
} catch (NumberFormatException e) {
return null;
}
if (obj instanceof Boolean) return (boolean) obj ? new AtomicLong(1L) : new AtomicLong();
if (obj instanceof Character) {
int delta = (char) obj - '0';
return delta < 0 || delta > 9 ? null : new AtomicLong(delta);
}
return null;
}
public static LongAdder getLongAdder(Object obj) {
if (obj == null) return null;
if (obj instanceof LongAdder) return (LongAdder) obj;
if (obj instanceof Number) {
LongAdder adder = new LongAdder();
adder.add(((Number) obj).longValue());
return adder;
}
if (obj instanceof CharSequence) try {
long value = Long.parseLong(obj.toString());
LongAdder adder = new LongAdder();
adder.add(value);
return adder;
} catch (NumberFormatException e) {
return null;
}
if (obj instanceof Boolean) {
LongAdder adder = new LongAdder();
if ((boolean) obj) adder.add(1L);
return adder;
}
if (obj instanceof Character) {
int delta = (char) obj - '0';
if (delta < 0 || delta > 9) return null;
LongAdder adder = new LongAdder();
adder.add(delta);
return adder;
}
return null;
}
public static DoubleAdder getDoubleAdder(Object obj) {
if (obj == null) return null;
if (obj instanceof DoubleAdder) return (DoubleAdder) obj;
if (obj instanceof Number) {
DoubleAdder adder = new DoubleAdder();
adder.add(((Number) obj).doubleValue());
return adder;
}
if (obj instanceof CharSequence) try {
double value = Double.parseDouble(obj.toString());
DoubleAdder adder = new DoubleAdder();
adder.add(value);
return adder;
} catch (NumberFormatException e) {
return null;
}
if (obj instanceof Boolean) {
DoubleAdder adder = new DoubleAdder();
if ((boolean) obj) adder.add(1D);
return adder;
}
if (obj instanceof Character) {
int delta = (char) obj - '0';
if (delta < 0 || delta > 9) return null;
DoubleAdder adder = new DoubleAdder();
adder.add(delta);
return adder;
}
return null;
}
public static String setScale(double val, int scale) {
return new BigDecimal(Double.toString(val)).setScale(scale, RoundingMode.HALF_UP).toString();
}
/**
* 移除尾部的0
*/
public static String stripTail0(String s) {
int len;
if ((len = NullHelp.length(s)) == 0) return s;
while (s.charAt(len - 1) == '0') --len;
if (s.charAt(len - 1) == '.') --len;
if (len == s.length()) return s;
char[] chars = new char[len];
s.getChars(0, len, chars, 0);
return new String(chars);
}
/**
* 格式化科学计数法字符串
*/
public static boolean scientific(CharSequenceVisitor visitor, CharConsumer action, String s, int idx) {
int len;
if (idx == 0 || (len = NullHelp.length(s)) == 0) return false;
int dot = s.indexOf(".");
if (idx > 0) {
if (dot == -1) {
visitor.accept(s, 0, len);
for (int i = 0; i < idx; ++i) action.accept('0');
return true;
}
int start = 0;
int end = dot + 1 + idx;
//去除首部的0
while (s.charAt(start) == '0') ++start;
if (start == dot) {
++start;
int limit = Math.min(len, end);
while (start < limit && s.charAt(start) == '0') ++start;
}
if (len <= end) {
if (start < dot) {
visitor.accept(s, start, dot);
visitor.accept(s, dot + 1, len);
} else if (start < len) visitor.accept(s, start, len);
for (int i = 0; i < end - len; ++i) action.accept('0');
return true;
}
if (start < dot) {
visitor.accept(s, start, dot);
visitor.accept(s, dot + 1, end);
} else if (start < end) visitor.accept(s, start, end);
else action.accept('0');
action.accept('.');
visitor.accept(s, end, len);
return true;
}
idx = -idx;
if (dot == -1) {
if (idx < len) {
visitor.accept(s, 0, len - idx);
action.accept('.');
visitor.accept(s, len - idx, len);
return true;
}
action.accept('0');
action.accept('.');
for (int i = 2; i < idx - len + 2; ++i) action.accept('0');
visitor.accept(s, 0, len);
return true;
}
if (idx < dot) {
visitor.accept(s, 0, dot - idx);
action.accept('.');
visitor.accept(s, dot - idx, dot);
visitor.accept(s, dot + 1, len);
return true;
}
action.accept('0');
action.accept('.');
for (int i = 2; i < idx - dot + 2; ++i) action.accept('0');
visitor.accept(s, 0, dot);
visitor.accept(s, dot + 1, len);
return true;
}
public static boolean scientific(CharSequenceVisitor visitor, CharConsumer action, String s) {
if (NullHelp.isBlank(s)) return false;
String[] arr;
if (s.indexOf('E') != -1) arr = s.split("E");
else if (s.indexOf('e') != -1) arr = s.split("e");
else return false;
if (arr.length != 2) return false;
if (!RegexHelp.P_DIGITAL.matcher(arr[0]).matches() || !RegexHelp.P_BYTE.matcher(arr[1]).matches()) return false;
return scientific(visitor, action, arr[0], Integer.parseInt(arr[1]));
}
public static String scientific(String s, int idx) {
if (idx == 0 || NullHelp.isEmpty(s)) return s;
StringBuilder sb = new StringBuilder();
return scientific(sb::append, sb::append, s, idx) ? sb.toString() : s;
}
public static String scientific(String s) {
if (NullHelp.isBlank(s)) return s;
StringBuilder sb = new StringBuilder();
return scientific(sb::append, sb::append, s) ? sb.toString() : s;
}
private static final char[] DIGIT = {'零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'};
private static final char[] INDEX = {'拾', '佰', '仟', '万', '亿'};
private static final char[] UNIT = {'元', '角', '分'};
private static final char I = '整';
/**
* 转大写人民币
* 会截取最多两位小数(不做进位处理),如需四舍五入需要提前处理数据
*/
public static void toCapitalRmb(CharConsumer action, CharSupplier tail, Runnable cancelTail, double val) {
String s = Double.toString(val);
int end = s.length();
int R = end;
int dot = s.indexOf('.');
if (dot != -1) {
//移除尾部的0
while (s.charAt(end - 1) == '0') --end;
//获取整数的右边界
if (s.charAt(end - 1) == '.') R = --end;
else R = dot;
}
//处理整数部分
toCapitalRmb0(s, 0, R, action, tail, cancelTail);
if (tail.getAsChar() == DIGIT[0]) cancelTail.run();
action.accept(UNIT[0]);
if (R == end) {
action.accept(I);
return;
}
//小数加零
action.accept(DIGIT[0]);
//只取两位到分
end = Math.min(dot + 3, end);
for (int i = dot + 1; i < end; ++i)
if (s.charAt(i) != '0') {
action.accept(DIGIT[s.charAt(i) - '0']);
action.accept(UNIT[i - dot]);
}
}
private static void toCapitalRmb0(String s, int L, int R, CharConsumer action, CharSupplier tail, Runnable cancelTail) {
if (R - L >= 9) {
toCapitalRmb0(s, L, R - 8, action, tail, cancelTail);
dealRmb0(INDEX[4], action, tail, cancelTail);
toCapitalRmb0(s, R - 8, R, action, tail, cancelTail);
return;
}
if (R - L >= 5) {
toCapitalRmb0(s, L, R - 4, action, tail, cancelTail);
dealRmb0(INDEX[3], action, tail, cancelTail);
toCapitalRmb0(s, R - 4, R, action, tail, cancelTail);
return;
}
boolean mark0 = tail.getAsChar() == DIGIT[0];
char c;
for (int i = L; i < R; ++i) {
c = s.charAt(i);
if (c == '0') {
if (!mark0) {
action.accept(DIGIT[0]);
mark0 = true;
}
} else {
if (R - 2 - i > 0) {
action.accept(DIGIT[c - '0']);
action.accept(INDEX[R - 2 - i]);
} else if (R - 2 - i == 0) {
action.accept(DIGIT[c - '0']);
action.accept(INDEX[0]);
} else action.accept(DIGIT[c - '0']);
mark0 = false;
}
}
}
private static void dealRmb0(char c, CharConsumer action, CharSupplier tail, Runnable cancelTail) {
if (tail.getAsChar() == DIGIT[0]) {
cancelTail.run();
appendRmbIndex0(c, action, tail);
action.accept(DIGIT[0]);
} else appendRmbIndex0(c, action, tail);
}
private static void appendRmbIndex0(char c, CharConsumer action, CharSupplier tail) {
char prev = tail.getAsChar();
int prevIdx = -1;
int currentIdx = -1;
for (int i = 0; i < INDEX.length; ++i) {
if (prev == INDEX[i]) prevIdx = i;
if (c == INDEX[i]) currentIdx = i;
}
if (prevIdx <= currentIdx) action.accept(c);
}
public static String toCapitalRmb(double val) {
StringBuilder sb = new StringBuilder(20).append("人民币");
toCapitalRmb(sb::append, () -> sb.charAt(sb.length() - 1), () -> sb.deleteCharAt(sb.length() - 1), val);
return sb.toString();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy