
net.apexes.commons.lang.Numbers Maven / Gradle / Ivy
/*
* Copyright (c) 2018, apexes.net. All rights reserved.
*
* http://www.apexes.net
*
*/
package net.apexes.commons.lang;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author HeDYn
*
*/
public final class Numbers {
private Numbers() {}
public static BigDecimal min(BigDecimal value1, BigDecimal value2) {
Checks.verifyNotNull(value1, "value1");
Checks.verifyNotNull(value2, "value2");
return (value1.compareTo(value2) > 0) ? value2 : value1;
}
public static BigDecimal max(BigDecimal value1, BigDecimal value2) {
Checks.verifyNotNull(value1, "value1");
Checks.verifyNotNull(value2, "value2");
return (value1.compareTo(value2) > 0) ? value1 : value2;
}
public static boolean ne(BigDecimal value1, BigDecimal value2) {
return !eq(value1, value2);
}
public static boolean eq(BigDecimal value1, BigDecimal value2) {
if (value1 == null) {
return value2 == null;
} else if (value2 == null) {
return false;
}
return value1.compareTo(value2) == 0;
}
/**
* 返回去掉不影响数值大小的0后的BigDecimal
* @param value 数值
* @return 返回去掉不影响数值大小的0后的BigDecimal
*/
public static BigDecimal trimZero(BigDecimal value) {
if (value == null) {
return null;
}
return new BigDecimal(trimZeroString(value));
}
/**
* 将数值转为字符串形式并去掉不影响数值大小的0
* @param value 数值
* @return 返回去掉不影响数值大小的0后的字符串
*/
public static String trimZeroString(BigDecimal value) {
if (value == null) {
return "";
}
String str = value.toPlainString();
int dotIndex = str.indexOf('.');
if (dotIndex > 0) {
int i = str.length() - 1;
while (i > dotIndex) {
if (str.charAt(i) != '0') {
break;
}
i--;
}
if (i == dotIndex) {
i--;
}
str = str.substring(0, i + 1);
}
return str;
}
/**
* 获取指定数值的负数值,如果数值为 null 则返回 null
* @param value 数值
* @return 返回指定值的负数值,如果 value 为 null 则返回 null
*/
public static BigDecimal negate(BigDecimal value) {
return value == null ? null : value.negate();
}
/**
* 如果value为null返回BigDecimal.ZERO,否则返回value
* @param value 数值
* @return 返回数值或BigDecimal.ZERO
*/
public static BigDecimal nullToZero(BigDecimal value) {
return value == null ? BigDecimal.ZERO : value;
}
/**
* 如果value为null返回0,否则返回value
* @param value 数值
* @return 如果数值或0
*/
public static long nullToZero(Long value) {
return value == null ? 0 : value;
}
/**
* 如果value为null返回0,否则返回value
* @param value 数值
* @return 如果数值或0
*/
public static int nullToZero(Integer value) {
return value == null ? 0 : value;
}
/**
* 如果value为null返回0,否则返回value
* @param value 数值
* @return 如果数值或0
*/
public static short nullToZero(Short value) {
return value == null ? 0 : value;
}
/**
* 如果value为null返回0,否则返回value
* @param value 数值
* @return 如果数值或0
*/
public static double nullToZero(Double value) {
return value == null ? 0 : value;
}
/**
* 如果value为null返回0,否则返回value
* @param value 数值
* @return 如果数值或0
*/
public static float nullToZero(Float value) {
return value == null ? 0 : value;
}
/**
* 判断value1和value2的值是否相等,null的值仅等于null
* @param value1 数值1
* @param value2 数值2
* @return 如果相等就返回true,否则返回false
*/
public static boolean eqValue(BigDecimal value1, BigDecimal value2) {
if (value1 == null) {
return value2 != null;
}
return value2 != null && value1.compareTo(value2) == 0;
}
/**
* 返回指定数值的整数部分
* @param value 数值
* @return 返回指定数值的整数部分
*/
public static long integralPart(BigDecimal value) {
return value.setScale(0, RoundingMode.FLOOR).longValue();
}
/**
* 返回指定数值的小数部分
* @param value 数值
* @return 返回指定数值的小数部分
*/
public static long decimalPart(BigDecimal value) {
BigDecimal integralPart = value.setScale(0, RoundingMode.FLOOR);
BigDecimal decimal = value.subtract(integralPart);
return decimal.movePointRight(decimal.scale()).longValue();
}
/**
* 返回value的低bits位
* @param value 数值
* @param bits 位数
* @return 返回value的低bits位
*/
public static int low(int value, int bits) {
if (bits <= 0) {
return 0;
}
BigDecimal v = BigDecimal.valueOf(value);
if (v.precision() <= bits) {
return value;
}
v = v.movePointLeft(bits);
v = v.subtract(BigDecimal.valueOf(v.intValue()));
v = v.movePointRight(bits);
return v.intValue();
}
/**
* 返回value的高bits位
* @param value 数值
* @param bits 位数
* @return 返回value的高bits位
*/
public static int high(int value, int bits) {
if (bits <= 0) {
return 0;
}
BigDecimal v = BigDecimal.valueOf(value);
int i = v.precision() - bits;
if (i <= 0) {
return value;
}
return v.movePointLeft(i).intValue();
}
/**
* 返回指定位的值
* @param value 数值
* @param bitIndex 正数表示小数点前的第N位,负数表示小数点后的第N位。如:3表求小数点前的第3位,-1表示小数点后的第1位
* @return 返回指定位的值
*/
public static int bit(BigDecimal value, int bitIndex) {
if (bitIndex == 0) {
return 0;
}
String str = trimZeroString(value.abs());
int dotIndex = str.indexOf('.');
int i = bitIndex;
if (dotIndex > 0) {
i = dotIndex - bitIndex;
} else {
i = str.length() - i;
}
if (i < 0 || i >= str.length()) {
return 0;
}
return Integer.parseInt(String.valueOf(str.charAt(i)));
}
/**
* 将指定数值bits位向下对齐5,如:12.586第2位向下对齐的结果为12.55
* @param value 数值
* @param bitIndex 正数表示小数点前的第N位,负数表示小数点后的第N位。如:3表求小数点前的第3位,-1表示小数点后的第1位
* @return 返回向下对齐的数值
*/
public static BigDecimal floorOfFive(BigDecimal value, int bitIndex) {
String str = trimZeroString(value.abs());
int dotIndex = str.indexOf('.');
if (bitIndex == 0 && dotIndex < 0) {
return value;
}
BigDecimal newValue;
if (bitIndex == 0) {
newValue = new BigDecimal(str.substring(0, dotIndex));
} else {
if (dotIndex < 0) {
dotIndex = str.length();
}
int i = dotIndex - bitIndex;
if (i < 0) {
return BigDecimal.ZERO;
}
if (i >= str.length()) {
return value;
}
StringBuilder buf = new StringBuilder();
if (i > 0) {
buf.append(str.substring(0, i));
}
char c = str.charAt(i);
if (c > '5') {
buf.append("5");
} else {
buf.append("0");
}
for (i++; i < dotIndex; i++) {
buf.append("0");
}
newValue = new BigDecimal(buf.toString());
}
if (value.signum() < 0) {
newValue = newValue.negate();
}
return trimZero(newValue);
}
/**
* 从最后一位向前逐位向下对齐5,直到stopBits位(包含)为止,并返回每次对齐的结果
* @param value 数值
* @param stopBitIndex 停止向下对齐的位
* @return 返回每次对齐的结果
*/
public static List floorOfFiveByBitwise(BigDecimal value, int stopBitIndex) {
List resultList = new ArrayList<>();
value = trimZero(value);
int scale = value.scale();
while (scale != 0 && scale >= -stopBitIndex) {
value = floorOfFive(value, -scale);
resultList.add(value);
scale = value.scale();
}
if (stopBitIndex > 0) {
value = trimZero(value.movePointLeft(stopBitIndex));
scale = value.scale();
if (scale > 0) {
int bit = bit(value, 1);
while (scale != 0 || bit != 0) {
value = floorOfFive(value, -scale);
BigDecimal newValue = value.movePointRight(stopBitIndex);
resultList.add(newValue);
scale = value.scale();
bit = bit(newValue, 1);
}
}
}
return resultList;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy