Java 数字处理

前段时间系统需要对大部分的数字进行处理,于是写了一个封装类。下面是参考网上资料进行的总结。
Java中对数字处理一般有3种方法。
1,数字的格式化一般用DecimalFormat
DecimalFormat 是 NumberFormat 的一个具体子类,用于格式化十进制数字。该类设计有各种功能,使其能够分析和格式化任意语言环境中的数,包括对西方语言、阿拉伯语和印度语数字的支持。它还支持不同类型的数,包括整数 (123)、定点数 (123.4)、科学记数法表示的数 (1.23E4)、百分数 (12%) 和金额 ($123)。所有这些内容都可以本地化。 
DecimalFormat 包含一个模式 和一组符号 
符号含义: 
符号 位置 本地化? 含义
0 数字 阿拉伯数字
# 数字字 阿拉伯数字,如果不存在则显示为空
. 数字 小数分隔符或货币小数分隔符
- 数字 减号
, 数字 分组分隔符
E 数字 分隔科学计数法中的尾数和指数。在前缀或后缀中无需加引号。
; 子模式边界 分隔正数和负数子模式
% 前缀或后缀 乘以 100 并显示为百分数
/u2030 前缀或后缀 乘以 1000 并显示为千分数
¤(/u00A4) 前缀或后缀 货币记号,由货币符号替换。如果两个同时出现,则用国际货币符号替换。如果出现在某个模式中,则使用货币小数分隔符,而不使用小数分隔符。
' 前缀或后缀 用于在前缀或或后缀中为特殊字符加引号,例如 "'#'#" 将 123 格式化为 "#123"。要创建单引号本身,请连续使用两个单引号:"# o''clock"。
例子:
DecimalFormat df1 = new DecimalFormat("0.0");   
DecimalFormat df2 = new DecimalFormat("#.#");   
DecimalFormat df3 = new DecimalFormat("000.000");   
DecimalFormat df4 = new DecimalFormat("###.###");   
System.out.println(df1.format(12.34));   
System.out.println(df2.format(12.34));   
System.out.println(df3.format(12.34));   
System.out.println(df4.format(12.34));   
运行结果: 
12.3 
12.3 
012.340 
12.34  


DecimalFormat format = new DecimalFormat("###,####.000");   
System.out.println(format.format(111111123456.1227222));   
  
Locale.setDefault(Locale.US);   
DecimalFormat usFormat = new DecimalFormat("###,###.000");   
System.out.println(usFormat.format(111111123456.1227222));   
  
DecimalFormat addPattenFormat = new DecimalFormat();   
addPattenFormat.applyPattern("##,###.000");   
System.out.println(addPattenFormat.format(111111123456.1227));   
  
DecimalFormat zhiFormat = new DecimalFormat();   
zhiFormat.applyPattern("0.000E0000");   
System.out.println(zhiFormat.format(10000));   
System.out.println(zhiFormat.format(12345678.345));   
  
DecimalFormat percentFormat = new DecimalFormat();   
percentFormat.applyPattern("#0.000%");   
System.out.println(percentFormat.format(0.3052222));   
运行结果 :
1111,1112,3456.123 
111,111,123,456.123 
111,111,123,456.123 
1.000E0004 
1.235E0007 
30.522% 
如果使用具有多个分组字符的模式,则最后一个分隔符和整数结尾之间的间隔才是使用的分组大小。所以 "#,##,###,####" == "######,####" == "##,####,####"。
2,对数字精度要求比较高,一般用BigDecimal
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数,但在实际应用中,可能需要对更大或者更小的数进行运算和处理。一般情况下,对于那些不需要准确计算精度的数字,我们可以直接使用Float和Double处理,但是Double.valueOf(String) 和Float.valueOf(String)会丢失精度。所以开发中,如果我们需要精确计算的结果,则必须使用BigDecimal类来操作。


(1)加减乘除
BigDecimal m1 = new BigDecimal(12);
BigDecimal m2 = new BigDecimal(5);
// 加
System.out.println(m1.add(m2));// 17
// 减
System.out.println(m1.subtract(m2));// 7
// 乘
System.out.println(m1.multiply(m2));// 60
// 除
System.out.println(m1.divide(m2, 2,BigDecimal.ROUND_HALF_UP));//2.40
(2)进度取舍
BigDecimal actualValue = new BigDecimal(StringUtil.isNotEmpty(wipRecipeDataVO.getActualValue()) ? 
wipRecipeDataVO.getActualValue() : StringUtil.defaultString(wipRecipeDataVO.getValue()));
if(wipRecipeDataVO.getPrecision().length()==1) {
//四舍五入
actualValue = actualValue.setScale(Integer.parseInt(wipRecipeDataVO.getPrecision()), BigDecimal.ROUND_HALF_UP);
}else if(wipRecipeDataVO.getPrecision().startsWith("/")) {
//截取
actualValue = actualValue.setScale(Integer.parseInt(StringUtils.substringAfter(wipRecipeDataVO.getPrecision(),"/")), BigDecimal.ROUND_DOWN);
}else if(wipRecipeDataVO.getPrecision().startsWith("+")) {
////向上取舍
actualValue = actualValue.setScale(Integer.parseInt(StringUtils.substringAfter(wipRecipeDataVO.getPrecision(),"+")), BigDecimal.ROUND_CEILING);
}else {
throw new BusinessException("ERR-5027", new Object[] {wipRecipeDataVO.getWipEntityId().toString(), 
wipRecipeDataVO.getName(), wipRecipeDataVO.getPrecision()});
}


参数定义


ROUND_CEILING 
Rounding mode to round towards positive infinity. 
向正无穷方向舍入 


ROUND_DOWN 
Rounding mode to round towards zero. 
向零方向舍入 


ROUND_FLOOR 
Rounding mode to round towards negative infinity. 
向负无穷方向舍入 


ROUND_HALF_DOWN 
Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round down. 
向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5 


ROUND_HALF_EVEN 
Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor. 
向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP ,如果是偶数,使用ROUND_HALF_DOWN 




ROUND_HALF_UP 
Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up. 
向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6 




ROUND_UNNECESSARY 
Rounding mode to assert that the requested operation has an exact result, hence no rounding is necessary. 
计算结果是精确的,不需要舍入模式 




ROUND_UP 
Rounding mode to round away from zero. 
向远离0的方向舍入


3,处理对数字精度要求不高的用Math
Math.ceil()执行向上舍入,即它总是将数值向上舍入为最接近的整数;
Math.floor()执行向下舍入,即它总是将数值向下舍入为最接近的整数;
Math.round()执行标准舍入,即它总是将数值四舍五入为最接近的整数(这也是我们在数学课上学到的舍入规则)。
// Math.ceil(Double a)返回大于等于(>=a)的最大整数
System.out.println(Math.ceil(1.3));// 2.0


// Math.floor(Double a)返回小于等于(<=a)的最大整数
System.out.println(Math.floor(1.3));// 1.0


// Math.rint(Double a)返回离a最近的整数,如果同为整数且同样接近则取偶数
System.out.println(Math.rint(0.5));// 0.0
System.out.println(Math.rint(1.5));// 2.0
System.out.println(Math.rint(0.3));// 0.0


// Math.round(Double a)将参数(a+0.5)之后向下取整整数,
System.out.println(Math.round(1.4));// 1 加上0.5之后变成1.9向下取整等于1
System.out.println(Math.round(1.5));// 1 加上0.5之后变成2向下取整等于2
System.out.println(Math.round(1.6));// 2 加上0.5之后变成2.1向下取整等于2
System.out.println(Math.round(-1.4));// -1 加上0.5之后变成-0.9向下取整等于-1
System.out.println(Math.round(-1.5));// -1 加上0.5之后变成-1向下取整等于-1
System.out.println(Math.round(-1.6));// -2 加上0.5之后变成-1.1向下取整等于-2


// Math.max()取最大值
System.out.println(Math.max(1, 2));// 2
// Math.min()取最小值
System.out.println(Math.min(1, 2));// 2
// Math.abs()取绝对值
System.out.println(Math.abs(-100));// 100


// Math.random()产生0~1之间的double型数字
System.out.println(Math.random());// 结果等于(0<=Math.random()<1.0)

你可能感兴趣的:(java)