Java 在 java.math 包中提供的 API 类 BigDecimal,用来对超过 16位有效位的数进行精确的计算。
对于那些不需要准确计算精度的数字,我们可以直接使用 Float 和 Double处理,但是 **Double.valueOf(String)和Float.valueOf(String)**会丢失精度。所以在开发过程总使用精确的计算必须使用 BigDecima 类来操作。
构造函数 | 解释 |
---|---|
BigDecimal(int) | 创建一个具有参数所指定整数值的对象 |
BigDecimal(double) | 创建一个具有参数所指定双精度值的对象 |
BigDecimal(long) | 创建一个具有参数所指定单精度值的对象 |
BigDecimal(String) | 创建一个具有参数所指定以字符串表示的数值的对象 |
方法名称 | 参数 | 作用 | 返回值 |
---|---|---|---|
add | BigDecimal | 与对象值进行加法运算 | BigDecimal |
subtract | BigDecimal | 与对象值进行相减运算 | BigDecimal |
multiply | BigDecimal | 与对象中的值进行相乘 | BigDecimal |
toString | 无 | 将对象中的值转成字符串 | String |
doubleValue | 无 | 将对象中的值转成双精度浮点型 | double |
floatValue | 无 | 将对象中的值转成单精度浮点型 | float |
longValue | 无 | 将对象中的值转成长整型 | long |
intValue | 无 | 将对象中的值转成整型 | int |
由于 NumberFormat 类(数字格式化类)的 format() 方法可以使用 BigDecimal 对象作为其参数,可以利用 BigDecimal 对超出 16 位有效数字的货币值、百分值,以及一般数值进行格式化控制。
创建 BigDecimal 对象,进行 BigDecimal 的算术运算后,分别建立对货币和百分比格式化的引用,最后利用 BigDecimal 对象作为 format() 方法参数,输出其格式化的货币和百分比。
- NumberFormat 是所有数值格式的抽象基类。此类提供格式化和解析数值的接口。
- NumberFormat 可用于格式化和解析任何语言环境的数值。使代码能够完全独立于小数点、千位分隔符甚至所用特定小数位数的语言环境约定,并与数值格式是否为偶小数无关。
函数 | 表述 |
---|---|
getInstance()、getNumberInstance()。 | 返回当前默认语言环境的通用数值格式。 |
getInstance(Locale)、getNumberInstance(Locale)。 | 返回指定语言环境的通用数值格式。 |
NumberFormat.setMinimumIntegerDigits(int)。 | 设置数的整数部分所允许的最小位数。 |
NumberFormat.setMaximumIntegerDigits(int)。 | 设置数的整数部分所允许的最大位数。 |
NumberFormat.setMinimumFractionDigits(int)。 | 设置最少小数点位数,不足的位数以0补位,超出的话按实际位数输出。 |
NumberFormat.setMaximumFractionDigits(int)。 | 设置最多保留小数位数,不足不补0。 |
DecimalFormat
值 | 表述 |
---|---|
“0” | 表示一位数值,如没有,显示0。如“0000.0000”,整数位或小数位>4,按实际输出,<4整数位前面补0小数位后面补0,凑足4位 |
“#” | 表示任意位数的整数。如没有,则不显示。在小数点位使用,只表示一位小数,超出部分四舍五入。 |
“#” | 无小数,小数部分四舍五入。 |
“.#” | 整数部分不变,一位小数,四舍五入。 |
“.##” | 整数部分不变,二位小数,四舍五入。 |
“.” | 表示小数点。 |
“,” | 与模式“0”一起使用,表示逗号。 |
package cn.chao.zero.test.Javaapi;
import org.apache.commons.lang3.RandomUtils;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;
import java.util.Random;
/**
* TODO
*
* @author RobertChao
* @date 2020/5/31 21:34
* @see cn.chao.zero.test.Javaapi
*/
public class MathTest {
public static void main(String[] args) {
System.out.println(Math.round(-0.5));
System.out.println(Math.round(0.5));
System.out.println("System.currentTimeMillis() ="+System.currentTimeMillis()%100);
System.out.println("Math.random() ="+Math.random());
// 未携带种子 [0, 5)
System.out.println("未携带种子 new Random().nextInt(5) ="+new Random().nextInt(5));
System.out.println("未携带种子 new Random().nextInt(5) ="+new Random().nextInt(5));
// 携带种子 [0, 5)
System.out.println("携带种子 new Random(10).nextInt(5) ="+new Random(10).nextInt(5));
System.out.println("携带种子 new Random(10).nextInt(5) ="+new Random(10).nextInt(5));
System.out.println("返回指定的随机数 ="+RandomUtils.nextInt(1, 10));;
// 阿里代码规范:禁止使用 new BigDecimal(double)构造函数的方式把 double 类型转换为 BigDecimal 对象。
// 结果不可预知,
// 当 double 必须用作 BigDecimal 的源时,先使用 Double.toString(double) 方法,然后使用 BigDecimal(String) 构造方法,将 double 转换为 String 。
BigDecimal bigDecimal = new BigDecimal(0.1);
System.out.println(bigDecimal);
// String 构造方法是完全可以预知的。
BigDecimal decimal = new BigDecimal("0.1");
System.out.println(decimal);
// BigDecimal 的使用 比较大小
BigDecimal decimal1 = new BigDecimal("0.1");
BigDecimal decimal2 = new BigDecimal("0.2");
int i = decimal1.compareTo(decimal2);
switch(i){
case 1:
System.out.println("大于");
break;
case 0:
System.out.println("等于");
break;
case -1:
System.out.println("小于");
break;
default:
System.out.println("无");
break;
}
// 格式化内容
// 建立货币类型的格式化 currency 货币
NumberFormat currencyInstance = NumberFormat.getCurrencyInstance();
// 建立百分比的格式化 percent 百分比
NumberFormat percentInstance = NumberFormat.getPercentInstance();
// 百分比小数点三位
percentInstance.setMaximumFractionDigits(2);
System.out.println("贷款金额:"+ currencyInstance.format(new BigDecimal("1500")));
System.out.println("百分比:"+ percentInstance.format(new BigDecimal("0.1314")));
System.out.println("计算结果:"+ currencyInstance.format(decimal1.multiply(decimal2)));
// 0.00 的货币格式设置
System.out.println(formatNumber(new BigDecimal("0.00000")));
System.out.println(formatNumber(new BigDecimal("0.234")));
System.out.println(formatNumber(new BigDecimal("1.234")));
// numberFormat 的使用
numberFormat();
// decimalFormat 的使用
decimalFormat();
}
// 货币价值设置
public static String formatNumber(BigDecimal bigDecimal) {
DecimalFormat format = new DecimalFormat("0.00");
if (BigDecimal.ZERO.compareTo(bigDecimal)==0) {
return "0.00";
} else if ((BigDecimal.ZERO.compareTo(bigDecimal) > 0) && (BigDecimal.ONE.compareTo(bigDecimal)<0)) {
return "0"+format.format(bigDecimal);
} else {
return format.format(bigDecimal);
}
}
/**
* numberFormat 的测试方法
*/
private static void numberFormat() {
double d = 12345.676688000;
NumberFormat nf = NumberFormat.getNumberInstance();
// 12,345.677 默认只保留到小数点后三位
System.out.println(nf.format(d));
nf.setMinimumIntegerDigits(2);
// 12,345.677 整数部分大于2位按默认最大小数位数3位输出
System.out.println(nf.format(d));
nf.setMaximumIntegerDigits(3);
// 345.677 整数3位,默认小数位数 3 位输出
System.out.println(nf.format(d));
d = 1234.0;
nf.setMaximumIntegerDigits(3);
// 234 整数部分最多3位,默认小数位数 3 位。
System.out.println(nf.format(d));
// -------------------------------
nf = NumberFormat.getInstance();
d = 12345.6766;
nf.setMinimumFractionDigits(1);
// 12,345.677 小数部分大于1位,按默认最大小数位数3位输出
System.out.println(nf.format(d));
nf.setMinimumFractionDigits(5);
// 12,345.67660 不够位数补0
System.out.println(nf.format(d));
nf.setMaximumFractionDigits(1);
// 12,345.7 最大小数位为 1 位,四舍五入。
System.out.println(nf.format(d));
// ----------------------------- 英国
nf = NumberFormat.getNumberInstance(Locale.US);
d = 12345.6789;
// 12,345.679 三位整数逗号隔开
System.out.println(nf.format(d));
// ----------------------------- 法国
nf = NumberFormat.getNumberInstance(Locale.FRANCE);
// 12 345,679 三位整数空格隔开
System.out.println(nf.format(d));
}
/**
* decimalformat 的测试方法
*/
private static void decimalFormat() {
double d1 = 123456.789, d2 = 12.3456;
DecimalFormat nf = new DecimalFormat("0000.000");
// d1=123456.789 d2=0012.346
System.out.println("d1=" + nf.format(d1) + " d2=" + nf.format(d2));
nf = new DecimalFormat("#");
// d1=123457
System.out.println("d1=" + nf.format(d1));
nf = new DecimalFormat(".####");
// d1=123456.789
System.out.println("d1=" + nf.format(d1));
// d1=0012,3456.78900
nf = new DecimalFormat("0000,0000.00000");
System.out.println("d1=" + nf.format(d1));
}
}