NumericUtil工具類(實現數字及數字格式化的基本功能:精確的加減乘除法、金額數字轉 成中文等。)
阿新 • • 發佈:2018-11-27
package com.cl.frame.clfbs.common;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
/**
* @版權:福富軟體 版權所有 (c) 2007
* @檔案:com.ffcs.crm.common.util.numeric.NumericUtil.java
* @所含類:NumericUtil
* @author: lovem
* @version : V1.0
* @see:
* @建立日期:2018-06-17
* @功能說明:實現數字及數字格式化的基本功能<br>
* < >包括:精確的加減乘除法、金額數字轉 成中文等。
* @修改記錄: =============================================================<br>
* 日期:2018-06-17 lovem 建立
* =============================================================<br>
*/
public class NumericUtil {
// 預設除法運算精度
private static final int DEF_DIV_SCALE = 10;
//字母隨機陣列,去除了i,o等歧義字母
final static String[] letters = {"a","b","c","d","e","f","g","h","j","k","m","n","p","q","r","s","t","u","v","w","x","y"};
//數字隨機陣列,去除了0和1等歧義數字
final static String[] numbers = {"2" ,"3","4","5","6","7","8","9"};
/**
* 建構函式.
*/
protected NumericUtil() {
}
/**
* 提供精確的加法運算。
*
* @param v1
* 被加數
* @param v2
* 加數
* @return 兩個引數的和
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static double add(final double v1, final double v2) {
final BigDecimal b1 = new BigDecimal(Double.toString(v1));
final BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
/**
* 提供精確的減法運算。
*
* @param v1
* 被減數
* @param v2
* 減數
* @return 兩個引數的差
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static double subtract(final double v1, final double v2) {
final BigDecimal b1 = new BigDecimal(Double.toString(v1));
final BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
/**
* 提供精確的乘法運算。
*
* @param v1
* 被乘數
* @param v2
* 乘數
* @return 兩個引數的積
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static double multiply(final double v1, final double v2) {
final BigDecimal b1 = new BigDecimal(Double.toString(v1));
final BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供(相對)精確的除法運算,當發生除不盡的情況時,精確到 小數點以後10位,以後的數字四捨五入。
*
* @param v1
* 被除數
* @param v2
* 除數
* @return double
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static double divide(final double v1, final double v2) {
return NumericUtil.divide(v1, v2, NumericUtil.DEF_DIV_SCALE);
}
/**
* 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale引數指 定精度,以後的數字四捨五入。
*
* @param v1
* 被除數
* @param v2
* 除數
* @param scale
* 表示表示需要精確到小數點以後幾位。
* @return double 兩個引數的商
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static double divide(final double v1, final double v2, final int scale) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
final BigDecimal b1 = new BigDecimal(Double.toString(v1));
final BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供精確的小數位四捨五入處理。
*
* @param v
* 需要四捨五入的數字
* @param scale
* 小數點後保留幾位
* @return 四捨五入後的結果
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static double round(final double v, final int scale) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
final BigDecimal b = new BigDecimal(Double.toString(v));
final BigDecimal one = new BigDecimal("1");
return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 將數字金額(BigDecimal型別)轉換為中文金額.
*
* @param bigdMoneyNumber
* 轉換前的數字金額
* @return String 中文金額
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static String lowerToUpperOfMoney(final BigDecimal bigdMoneyNumber) {
final String[] straChineseUnit = new String[] {"分", "角", "圓", "拾", "佰", "仟", "萬", "拾", "佰",
"仟", "億", "拾", "佰", "仟" };
// 中文數字字元陣列
final String[] straChineseNumber = new String[] {"零", "壹", "貳", "叄", "肆", "伍", "陸", "柒",
"捌", "玖" };
String strChineseCurrency = "";
// 零數位標記
boolean bZero = true;
// 中文金額單位下標
int chineseUnitIndex = 0;
try {
if (bigdMoneyNumber.intValue() == 0) {
return "零圓整";
}
// 處理小數部分,四捨五入
double doubMoneyNumber = Math.round(bigdMoneyNumber.doubleValue() * 100);
// 是否負數
final boolean bNegative = doubMoneyNumber < 0;
// 取絕對值
doubMoneyNumber = Math.abs(doubMoneyNumber);
// 迴圈處理轉換操作
while (doubMoneyNumber > 0) {
// 整的處理(無小數位)
if (chineseUnitIndex == 2 && strChineseCurrency.length() == 0) {
strChineseCurrency = strChineseCurrency + "整";
}
// 非零數位的處理
if (doubMoneyNumber % 10 > 0) {
strChineseCurrency = straChineseNumber[(int) doubMoneyNumber % 10]
+ straChineseUnit[chineseUnitIndex] + strChineseCurrency;
bZero = false;
} else { // 零數位的處理
// 元的處理(個位)
if (chineseUnitIndex == 2) {
// 段中有數字
if (doubMoneyNumber > 0) {
strChineseCurrency = straChineseUnit[chineseUnitIndex]
+ strChineseCurrency;
bZero = true;
}
} else if (chineseUnitIndex == 6 || chineseUnitIndex == 10) { // 萬、億數位的處理
// 段中有數字
if (doubMoneyNumber % 1000 > 0) {
strChineseCurrency = straChineseUnit[chineseUnitIndex]
+ strChineseCurrency;
}
}
// 前一數位非零的處理
if (!bZero) {
strChineseCurrency = straChineseNumber[0] + strChineseCurrency;
}
bZero = true;
}
doubMoneyNumber = Math.floor(doubMoneyNumber / 10);
chineseUnitIndex++;
}
// 負數的處理
if (bNegative) {
strChineseCurrency = "負" + strChineseCurrency;
}
} catch (final Exception e) {
return "";
}
return strChineseCurrency;
}
/**
* 將小寫金額(double型別)轉化為人民幣大寫格式.
*
* @param je
* 轉換前的小寫數字金額
* @return String 中文金額
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static String lowerToUpperOfMoney(final double je) {
String money = ""; // 轉換後的字串
final String num = "零壹貳叄肆伍陸柒捌玖";
final String[] unit = {"元", "拾", "佰", "仟", "萬", "拾萬", "佰萬", "仟萬", "億", "拾億", "佰億", "仟億" };
String s = String.valueOf(je); // 將金額轉換為字串
final int a = s.indexOf("+"); // 判斷s是否包含'+',如1.67E+4
final int e = s.indexOf("E"); // 判斷s是否包含'E',如1.67E+4
if (je == 0.00) {
return money;
}
// 如果包含'E'(該金額是以科學記數法表示,則轉換成普通表示法)
if (e != -1) {
int index = 0; // 指數值
if (a == -1) {
index = Integer.parseInt(s.substring(e + 1)); // 取得指數值
} else {
index = Integer.parseInt(s.substring(a + 1)); // 取得指數值
}
final String sub1 = s.substring(0, e); // 取得尾數值
final int dot = sub1.indexOf("."); // 尾數的小數點位置
// 如果不含有小數點,則在後面補index個'0'
if (dot == -1) {
for (int i = 1; i <= index; i++) {
s = sub1 + "0";
}
} else { // 如果含有小數點,則向後移動小數點index位
final String sub11 = sub1.substring(0, dot); // 小數點前面的字串
String sub12 = sub1.substring(dot + 1); // 小數點後面的字串
if (index >= sub12.length()) {
final int j = index - sub12.length();
for (int i = 1; i <= j; i++) {
sub12 = sub12 + "0";
}
} else {
sub12 = sub12.substring(0, index) + "." + sub12.substring(index);
}
s = sub11 + sub12;
}
}
final int sdot = s.indexOf("."); // s中小數點的位置
String beforeDot = ""; // 小數點前面的字串
String afterDot = ""; // 小數點後面的字串
// 如果包含小數點
if (sdot != -1) {
beforeDot = s.substring(0, sdot);
afterDot = s.substring(sdot + 1);
} else { // 不包含小數點
beforeDot = s;
}
final int bl = beforeDot.length();
boolean zero = false; // 數字是否為零
int z = 0; // '0'的個數
// 逐位取數字
for (int j = 0, i = bl - 1; j <= bl - 1; j++, i--) {
final int number = Integer.parseInt(String.valueOf(beforeDot.charAt(j)));
if (number == 0) {
zero = true;
z++;
} else {
zero = false;
z = 0;
}
if (zero && z == 1) {
money += "零";
} else if (zero) {
} else if (!zero) {
money += num.substring(number, number + 1) + unit[i];
}
}
// 刪去多餘的'萬'和'億'
for (int i = 1; i <= 2; i++) {
String ss = "";
if (i == 1) {
ss = "萬";
} else {
ss = "億";
}
final int last = money.lastIndexOf(ss);
if (last != -1) {
String moneySub1 = money.substring(0, last);
final String moneySub2 = money.substring(last, money.length());
int last2 = moneySub1.indexOf(ss);
while (last2 != -1) {
moneySub1 = moneySub1.substring(0, last2)
+ moneySub1.substring(last2 + 1, moneySub1.length());
last2 = moneySub1.indexOf(ss);
}
money = moneySub1 + moneySub2;
}
}
// money中是否包含'元'
final int yuan = money.indexOf("元");
// 如果不包含'元'
if (yuan == -1) {
final int zi = money.lastIndexOf("零");
// 如果最後一位字元為'零',則刪除它
if (zi == money.length() - 1) {
money = money.substring(0, money.length() - 1) + "元"; // 在money最後加上'元'
}
}
// 如果小數點後面的字串不為空,則處理'角','分'
if (!afterDot.equals("")) {
int al = afterDot.length();
if (al > 2) { // 如果字串長度大於2,則截斷
afterDot = afterDot.substring(0, 2);
al = afterDot.length();
}
// 如果字串不為'0'或'00',則處理,否則不進行處理
if (!afterDot.equals("0") && !afterDot.equals("00")) {
// 逐位取得字元
for (int i = 0; i < al; i++) {
final int number = Integer.parseInt(String.valueOf(afterDot.charAt(i)));
if (number != 0 && i == 0) {
money += num.substring(number, number + 1) + "角";
} else if (number != 0 && i == 1) {
money += num.substring(number, number + 1) + "分";
} else if (number == 0 && i == 0) {
money += "零";
}
}
}
}
// 如果不包含'角','分'則在最後加上'整'字
if (money.indexOf("角") == -1 && money.indexOf("分") == -1) {
money += "整";
}
return money;
}
/**
* 將double數轉化為指定位數的字串.
*
* @param num
* 待轉換的float數
* @param digits
* 小數點後的位數
* @return String 指定小數位數的字串
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static String getNumberFormat(final float num, final int digits) {
String thenum;
final NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(digits);
nf.setMinimumFractionDigits(digits);
thenum = nf.format(num).toString();
return thenum;
}
/**
* 將double數轉化為指定位數的字串.<br>
* 例如: NumericUtil.getNumberFormat(123456.12345,3)
* 的結果為123,456.123,注意小數點最後一位四捨五入
*
* @param num
* 待轉換的double數
* @param digits
* 小數點後的位數
* @return String 指定小數位數的字串
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static String getNumberFormat(final double num, final int digits) {
String thenum;
final NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(digits);
nf.setMinimumFractionDigits(digits);
thenum = nf.format(num).toString();
return thenum;
}
/**
* 將BigDecimal數轉化為指定位數的字串.<br>
* 例如: NumericUtil.getNumberFormat(new BigDecimal(123456.12345),3)
* 的結果為123,456.123,注意小數點最後一位四捨五入
*
* @param num
* 待轉換的BigDecimal數
* @param digits
* 小數點後的位數
* @return String 指定小數位數的字串
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static String getNumberFormat(BigDecimal num, final int digits) {
String thenum = "";
if (num == null) {
num = new BigDecimal(0);
}
try {
final NumberFormat nf = NumberFormat.getInstance();
nf.setMaximumFractionDigits(digits);
nf.setMinimumFractionDigits(digits);
thenum = nf.format(num).toString();
} catch (final NumberFormatException nfex) {
throw new NumberFormatException(nfex.toString());
}
return thenum;
}
/**
* 格式字串為double輸出.
*
* @param lpNumberFormat
* 待格式化的字串
* @return double double數值
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static double getNumberFormatStrToDouble(final String lpNumberFormat) {
double lpReturnNumber = 0;
final NumberFormat nf = NumberFormat.getInstance();
try {
final Number lpResultNumber = nf.parse(lpNumberFormat);
lpReturnNumber = lpResultNumber.doubleValue();
} catch (final ParseException pe) {
}
return lpReturnNumber;
}
/**
* 格式字串為float輸出.
*
* @param lpNumberFormat
* 待格式化的字串
* @return float float數值
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static float getNumberFormatStrToFloat(final String lpNumberFormat) {
float lpReturnNumber = 0;
final NumberFormat nf = NumberFormat.getInstance();
try {
final Number lpResultNumber = nf.parse(lpNumberFormat);
lpReturnNumber = lpResultNumber.floatValue();
} catch (final ParseException pe) {
}
return lpReturnNumber;
}
/**
* 將字串轉化為BigDecimal型別.
*
* @param str
* 待轉換的字串
* @return BigDecimal 轉換後的BigDecimal,如果字串為null, 那麼BigDecimal為new
* BigDecimal("0");
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static BigDecimal toBigDecimal(String str) {
BigDecimal lpReturnValue;
try {
if (str == null) {
str = "0";
}
lpReturnValue = new BigDecimal(str);
} catch (final NumberFormatException nfe) {
lpReturnValue = new BigDecimal(0);
}
return lpReturnValue;
}
/**
* 將字串轉化為double型別 Converts a string to double. If fails is not throwing a
* NumberFormatException, instead return 0.
*
* @param str
* 待轉換的字串
* @return double資料
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static double toDouble(String str) {
double lpResult = 0;
if (str == null) {
str = "";
} else {
str = str.trim();
}
try {
lpResult = Double.parseDouble(str);
} catch (final NumberFormatException nfe) {
}
return lpResult;
}
/**
* 將字串轉化為short型別 Converts a string to short. If fails is not throwing a
* NumberFormatException, instead return 0.
*
* @param str
* 待轉換的字串
* @return int資料
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static short toShort(String str) {
short lpResult = 0;
if (str == null) {
str = "";
} else {
str = str.trim();
}
try {
lpResult = Short.parseShort(str);
} catch (final NumberFormatException nfe) {
}
return lpResult;
}
/**
* 將字串轉化為int型別 Converts a string to integer. If fails is not throwing a
* NumberFormatException, instead return 0.
*
* @param str
* 待轉換的字串
* @return int 資料
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static int toInt(String str) {
int lpResult = 0;
if (str == null) {
str = "";
} else {
str = str.trim();
}
try {
lpResult = Integer.parseInt(str);
} catch (final NumberFormatException nfe) {
}
return lpResult;
}
/**
* 將字串轉化為float型別 Converts a string to float. If fails is not throwing a
* NumberFormatException, instead return 0.
*
* @param str
* 待轉換的字串
* @return float 資料
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static float toFloat(String str) {
float lpResult = 0;
if (str == null) {
str = "";
} else {
str = str.trim();
}
try {
lpResult = Float.parseFloat(str);
} catch (final NumberFormatException nfe) {
}
return lpResult;
}
/**
* 將字串轉化為long型別 Converts a string to long. If fails is not throwing a
* NumberFormatException, instead return 0.
*
* @param str
* 待轉換的字串
* @return long 資料
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static long toLong(String str) {
long lpResult = 0;
if (str == null) {
str = "";
} else {
str = str.trim();
}
try {
lpResult = Long.parseLong(str);
} catch (final NumberFormatException nfe) {
}
return lpResult;
}
/**
* 當變數為空時返回零.
*
* @param obj
* Object
* @return int
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static int nullToZero(final Object obj) {
int result = 0;
if (obj == null || obj.toString().equals("")) {
result = 0;
} else {
result = new Integer(obj.toString()).intValue();
}
return result;
}
/**
* 當變數為空時返回零.
*
* @param obj
* Object
* @return BigDecimal
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static BigDecimal nullToBigDecimalZero(final Object obj) {
BigDecimal result = new BigDecimal("0");
if (obj == null || obj.toString().equals("")) {
result = new BigDecimal("0");
} else {
result = new BigDecimal(obj.toString());
}
return result;
}
/**
* @param obj
* Object
* @return String
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static String nullToStringZero(final Object obj) {
BigDecimal result = new BigDecimal("0");
if (obj == null || obj.toString().equals("")) {
result = new BigDecimal("0");
} else {
result = new BigDecimal(obj.toString());
}
return result.toString();
}
/**
* @param obj
* Object
* @return Long
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static Long nullToLongZero(final Object obj) {
Long result = new Long(0);
try {
if (obj == null || obj.toString().equals("")) {
result = new Long(0);
} else {
result = new Long(obj.toString());
}
} catch (final Exception ex) {
result = new Long(0);
}
return result;
}
public static Long nullToLongZero(final Object obj, final Long rpt) {
Long result = nullToLongZero(obj);
if(result == 0L){
result = rpt;
}
return result;
}
public static Integer nullToIntegerZero(final Object obj) {
Integer result = new Integer(0);
try {
if (obj == null || obj.toString().equals("")) {
result = new Integer(0);
} else {
result = new Integer(obj.toString());
}
} catch (final Exception ex) {
result = new Integer(0);
}
return result;
}
/**
* @param obj
* Double
* @return Double
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static Double nullToDoubleZero(final Double obj) {
Double result = new Double(0);
if (obj == null) {
result = new Double(0);
} else {
final DecimalFormat format = new DecimalFormat("#.000");
result = new Double(format.format(obj));
}
return result;
}
/**
* @param obj
* Object
* @return Double
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static Double nullToDoubleZero(final Object obj) {
Double result = new Double(0);
try {
if (obj == null) {
result = new Double(0);
} else {
result = new Double(obj.toString());
}
} catch (final Exception e) {
}
return result;
}
/**
* 將對像轉換成Float型別,當對像為空時返回0
* .
*
* @param obj
* @return
* @author lovem
* 2018-06-17 lovem
*/
public static Float nullToFloatZero(final Object obj) {
Float result = new Float(0);
try {
if(obj != null){
result = Float.valueOf(obj.toString());
}
} catch (final Exception e) {
}
return result;
}
/**
* 方法功能:
* 轉換大Long為int .
* @param lon 輸入大Long
* @return int 返回int
* @author: lovem
* @修改記錄:
* ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
public static int toInt(Long lon) {
int lpResult = 0;
try {
if (lon == null) {
lpResult = 0;
} else {
lpResult = lon.intValue();
}
} catch (final NumberFormatException nfe) {
}
return lpResult;
}
/**
* 根據密碼長度和是否包含字母引數來生成隨機碼.
*
* @param length 長度
* @param hasLetter 是否包含字母
* @return 隨機密碼
* @author lovem
* 2018-06-17 lovem
*/
public static String getRandomCode(int length, boolean hasLetter) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < length; i++) {
double random = Math.random();
if (hasLetter && random < 0.5 ) {
Double d = new Double(random * letters.length);
sb.append(letters[d.intValue()]);
} else {
Double d = new Double(random * numbers.length);
sb.append(numbers[d.intValue()]);
}
}
return sb.toString();
}
/**
* @param args
* String
* @author: lovem
* @修改記錄: ==============================================================<br>
* 日期:2018-06-17 lovem 建立方法,並實現其功能
* ==============================================================<br>
*/
/*
* public static void main(String args[]) { NumericUtil a = new
* NumericUtil(); BigDecimal big = new BigDecimal(123456.12345); }
*/
}