Java从入门到精通 第九章 数字处理类
做过开发的应该都知道涉及到金额计算的 不能出现过大的精度缺失,如果还是用开发语言 如java中处理浮点数的方式,那样子会有精度缺失的情况出现.同时在java中如果出现0.001~1000 0000返回之外的 会使用科学计数法,那样明显无法满足实际情况的出现.
Decimal
Decimal格式化工具类是 用于对常见格式数字处理的,比如首先创建Decimal对象实例,通过有参构造方法 传入设置格式。然后通过该类实例的 成员方法format(String s)将需要格式化参数 传进去,返回格式化成功的数字.
- DecimlaFormat特殊字符声明,目前来讲最常用的就是#与0.总结来看就是 0的话少的会补上,多的话回去掉.#的话少的话不会补,多的话回去掉。另外比较常用的就是.小数分隔符以及%百分号符。具体例子如下
数字运算
数学运算类 主要指的是Math类 针对 指数函数,三角函数,取值取舍等操作。(一般来用 实际开发中用到Math可能更多的是用三角函数,指数函数,数字取整取舍等操作。数字运算更多是用到BigDecimla更精度计算帮助类,BigInteger高精度整数计算类,暂不考虑)
- 三角函数运算(都是静态方法 直接使用类名调用)
Math.sin()正弦 Math.cos()余弦 Math.tan()正切 Math.PI常量表示π表示180° - 取整函数方法
这个方法尽管只能为了取整使用,但是对于后面BigDecimal的保留几位小数思路是一样的,都是分为几种模式 ceil向上取证,floor向下取整,round四舍五入模式,rint()取最近的值 有偶数选偶数.
随机数
随机数分为2种获取方式,一种是Math类中的random方法用于获取[0,1)之键的任意值,如果要获取其他区间数字(n,m)只需要 Math.random()*(m-n)+n.另外一种方法则是 Random.nextInt()等 获取衣蛾随机数。虽然看起来是可以获取到随机数的,但是实际上这2种方式是一种位随机数。这是一种通过当前时间 进过一些列复杂运算得出来的。说白了Math.random方法也是通过Random.nextDouble方法实现的。同时并非线程安全的,如果在高并发的情况下,可以看到nextDouble成员方法 的计算值可能出现重复。
大数字运算
大数字运算包括BigInteger高精度整形计算帮助类,BigDecimal高精度浮点数计算帮助类,其中用到比较多的是BigDecimal类,包含了基础的加减乘除算法,同时对于小数点约分和约分模式也可以设置。通常来讲会用到Round_HALF_UP四舍五入的模式比较多.
- public BigDecimal add(BigDecimal b2);将当前对象的值加上b1的值
- public BigDecimal sub(BigDecimal b2)将当前对象的值减去b2的值
- public BigDecimal mul(BigDecimal b2)将当前对象的值相乘b2的值
- public BigDecimal divide(BigDecimal b2,int scale,int roundingMode)将当前对象的值相乘b2的值,scale表示 需要保留的位数,roundingMode表示保留位数的处理模式。
- roundingMode的保留模式ROUND_UP 只管增加
- ROUND_DOWN 只管减少
- ROUND_CEIL 向上取整
- ROUND_FLOOR向下取整
- ROUND_HALF_UP 四舍五入(最常用的方式)
高精度计算帮助类(包含加减乘除等模式)
package com.bxd.core.util;
import java.math.BigDecimal;
public class HighPreciseComputor {
// 默认除法运算精度
private static final int DEF_DIV_SCALE = 10;
/**
* 提供精确的加法运算。
*
* @param v1 被加数
* @param v2 加数
* @return 两个参数的和
*/
public static double add(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
/**
* 提供精确的减法运算。
*
* @param v1 被减数
* @param v2 减数
* @return 两个参数的差
*/
public static double sub(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
/**
* 提供精确的乘法运算。
*
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public static double mul(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
*
* @param v1 被除数
* @param v2 除数
* @return 两个参数的商
*/
public static double div(double v1, double v2) {
return div(v1, v2, DEF_DIV_SCALE);
}
/**
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
*
* @param v1 被除数
* @param v2 除数
* @param scale 表示表示需要精确到小数点以后几位。
* @return 两个参数的商
*/
public static double div(double v1, double v2, int scale) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
/**
* 提供精确的小数位四舍五入处理。
*
* @param v 需要四舍五入的数字
* @param scale 小数点后保留几位
* @return 四舍五入后的结果
*/
public static double round(double v, int scale) {
if (scale < 0) {
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal("1");
return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
}
}