Java Math类、BigDecimal类、NumberFormat类、浮点数的精确度问题
Math类
Math提供了一系列的静态方法来进行数学运算。
Math.PI π
Math.E e
Math.toDegrees(double 弧度) 弧度转角度
Math.toRadians(double 角度) 角度转弧度
Math.sin/cos/tan()
Math.sqrt() 算数平方根
Math.exp() e的多少次方
Math.pow(x,y) x的y次方
Math.round/floor/ceil()
Math.log() 自然对数(以e为底)
Math.log10() 以10为底的对数
Math.abs() 绝对值
Math.min(x,y) 返回两个数中较小的一个
Math.max(x,y) 较大的一个
Math.random() 返回一个[0.0,1.0)之间的伪随机数。此方法无参数。
java中的似乎都是[x,y),包含左边,不包含右边。
BigDecimal类
一般情况下,计算机不能精确地表示浮点数。Bigdecimal类则可以精确地表示浮点数,并可以对浮点数进行精确的数学计算。
构造函数:
BigDecimal(String num) 传入一个String类型的数值,因为参数直接使用浮点数,计算机表示时会有误差,用字符串表示浮点数则不会有误差。
BigDecimal.valueOf(double num) 如果必须使用double作为参数,则可以使用静态方法来创建对象。
BigDecimal类提供了一系列方法来进行精确地数学运算:
add(BigDecimal bd) 加
subtract(BigDecimal bd) 减
multiply(BigDecimal bd) 乘
divide(BigDecimal bd) 除
2个操作数均为BigDecimal类型,返回值也为BigDecimal类型。
BigDecimal也提供了一个方法将BigDecimal转换为double:
doubleValue() //返回double型的值
示例:
package test; import java.math.BigDecimal; //需要实现Cloneable接口 public class Test{ public static void main(String[] args) { BigDecimal db1=new BigDecimal("1.23"); BigDecimal db2=new BigDecimal("1.3435"); //2个操作数、返回值均为BigDecimal类型 BigDecimal db3=db1.add(db2); //转换为double类型 System.out.println(db3.doubleValue()); //当然BigDecimal类型也可以直接输出,输出的值和double类型的完全一样 System.out.println(db3); } }
NumberFormat类
使用静态方法获取NumberFormat对象:
NumberFormat nf1=NumberFormat.getCurrencyInstance(Locale.CHINA); //获取指定国家的货币格式,比如中国为¥,美国为$。参数为Locale类的常量
NumberFormat nf2=NumberFormat.getIntegerInstance(); //获取整型数字格式,这个可缺省国家参数,使用默认的即可。格式化结果为整数
NumberFormat nf3=NumberFormat.getNumberInstance(); //获取通用的数字格式,可缺省国家参数,使用默认的即可。格式化结果保持原有的数值类型。
NumberFormat类的常用方法:
format(long number) 格式化数值,返回String
format(double number)
parse(String str) 将特定格式的String转化为Number类型(数值型)
示例:
nf1.format(12345) 返回字符串“¥12,345” 。会在最前面加上该国家的货币符号。从末尾起,每3位加一个逗号。
nf1.parse(“¥12,345”) 返回数值12345
nf2.format(12345) 返回字符串“12,345”
nf2.format(12345.678) 返回字符串"12,345",因为是nf2是Integer的格式,所以会先四舍五入转化为整型,再格式化
nf2.parse("12,345") 返回数值12345
nf3.format(12345) 返回字符串"12,345"
nf3.format(12345.678) 返回字符串"12,345.678",nf3是Number的格式(通用数字格式),会保留原有的数值类型,不会四舍五入。
nf3.parse("12,345") 返回数值12345
浮点数的精确度问题
题目:
分别获取数字的整数部分、小数部分,如15.12,整数部分为15,小数部分为0.12
package my_package; public class Divide { public static void main(String[] args) { double num = 12.345; //也可以指定调用的方法为static Divide d = new Divide(); //第一种 String[] arr1 = d.divide_1(num); System.out.print("整数部分:" + arr1[0] + " "); System.out.println("小数部分:" + arr1[1]); //第二种 String[] arr2 = d.divide_2(num); System.out.print("整数部分:" + arr2[0] + " "); System.out.println("小数部分:" + arr2[1]); } //将整数、小数拆分为数值,再放在一个字符串数组中返回。但由于计算机表示浮点数时有误差,所以小数部分并不精确 public String[] divide_1(double num){ //获取整数部分 int zhengshu=(int)num; //获取小数部分 double xiaoshu=num-zhengshu; //放在字符串数组中返回 String[] arr={String.valueOf(zhengshu),String.valueOf(xiaoshu)}; return arr; } // 转换为字符串,利用小数点分割,完全精确 public String[] divide_2(double num){ String str=String.valueOf(num); //小数点位置 int index=str.indexOf("."); String zhengshu=str.substring(0,index); String xiaoshu="0."+str.substring(index+1); return new String[]{zhengshu,xiaoshu}; } }