数学运算
1、保留两位小数
import java.math.BigDecimal;
public class MathUtil {
public static double reservedDecimal(double d,int digit){
BigDecimal bd = new BigDecimal(d);
/**
* BigDecimal.ROUND_HALF_UP 四舍五入
*/
double result = bd.setScale(digit, BigDecimal.ROUND_HALF_UP).doubleValue();
return result;
}
public static void main(String[] args) {
double v = reservedDecimal(32.3245, 4);
System.out.println(v);
}
}
RoundingMode.CEILING:
取右边最近的整数
RoundingMode.DOWN:
去掉小数部分取整,也就是正数取左边,负数取右边,相当于向原点靠近的方向取整
RoundingMode.FLOOR:
取左边最近的正数
RoundingMode.HALF_DOWN:
五舍六入,负数先取绝对值再五舍六入再负数
RoundingMode.HALF_UP:
四舍五入,负数原理同上
RoundingMode.HALF_EVEN:
这个比较绕,整数位若是奇数则四舍五入,若是偶数则五舍六入
2、 除法不丢失精度(BigDecimal)
除法不丢失精度,且保留指定位小数
public static void divideMethod(Double d1,Double d2,int digit){
BigDecimal b1 = new BigDecimal(d1);
BigDecimal b2 = new BigDecimal(d2);
//b1除以b2,保留digit位小数
Double diResult = b1.divide(b2,digit,RoundingMode.HALF_UP).doubleValue();
//b1乘以b2,保留digit位小数
double muResult = b1.multiply(b2).setScale(digit,RoundingMode.HALF_UP).doubleValue();
//b1加上b2,保留digit位小数
double addResult = b1.add(b2).setScale(digit,RoundingMode.HALF_UP).doubleValue();
//b1减去b2,保留digit位小数
double subResult = b1.subtract(b2).setScale(digit,RoundingMode.HALF_UP).doubleValue();
System.out.println(addResult);
System.out.println(subResult);
System.out.println(muResult);
System.out.println(diResult);
}
调用: divideMethod(23.89,43.98,4);
输出:
67.87
-20.09
1050.6822
0.5432
总结:
加:
a.add(b);
减:
a.subtract(b);
乘:
a.multiply(b);
除:
a.divide(b,2); //2是保留2位小数的意思
3、 double乘以Integer丢失精度问题
Double类型计算和转换时可能有精度丢失问题:
float和double类型主要是为了科学计算和工程计算而设计,他们执行二进制浮点运算,这是为了在广泛的数值范围上提供较为精确的快速近和计算而精心设计的。然而,他们并没有提供完全精确的结果,所以不应该被用于精确的结果的场合。浮点数达到一定大的数会自动使用科学计数法,这样的表示只是近似真实数而不等于真实数。当十进制小数位转换二进制的时候也会出现无限循环或者超过浮点数尾数的长度。
反面例子:
public static void useDoubleDivide(){
BigDecimal failCountBigDeci = BigDecimal.valueOf(0.14);
BigDecimal totalCountBigDeci = BigDecimal.valueOf(100);
Double bigDecimal = failCountBigDeci
.divide(totalCountBigDeci, 4, RoundingMode.HALF_UP).doubleValue();
String result = bigDecimal*100 +"%";
System.out.println(result);
}
输出:0.13999999999999999%
正面例子:
public static void useBigDecimalDivide(){
BigDecimal failCountBigDeci = BigDecimal.valueOf(0.1443333333);
BigDecimal totalCountBigDeci = BigDecimal.valueOf(100);
BigDecimal bigDecimal = failCountBigDeci
.divide(totalCountBigDeci, 4, RoundingMode.HALF_UP)
.multiply(BigDecimal.valueOf(100))
.setScale(2, RoundingMode.HALF_UP);
String result = bigDecimal+"%";
System.out.println(result);
}
输出:0.14%
结论:除法用Bigdecimal的divide,乘法用Bigdecimal的multiply,且也要写setScale方法,要不然默认保留0位小数
4、 计算一个数的m次方
import java.math.BigDecimal;
public class MathUtil {
public static double MathPower(double n,double m){
double pow = Math.pow(n, m);
return pow;
}
public static void main(String[] args) {
double v = MathPower(3, 3);
System.out.println(v);
}
}
5、开方运算
Math.sqrt(a) // a是double类型
public static void sqrt(){
double a= 11;
double sqrt = Math.sqrt(a);
double bigDecimalSqrt = BigDecimal.valueOf(sqrt)
.setScale(2,RoundingMode.HALF_UP)
.doubleValue();
System.out.println(bigDecimalSqrt);
}
输出:3.32
6、 位移运算
public static void main(String[] args) {
Integer a = 2 <<10;
System.out.println(a);
}
输出2048
2=0010
2<<10 = 00100000000000
1x2的11次方 = 2048