Java double 保留一个小数
两种方法
@Test public void test2() { double f = 234.353333000000000000000000; BigDecimal b = new BigDecimal(f); double f1 = b.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue(); System.out.println(f1); } @Test public void test3() { double f = 234.353333000000000000000000; java.text.DecimalFormat df = new java.text.DecimalFormat("#.0"); String format = df.format(f); System.out.println(format); }
大概最常见的是第一种,推荐使用BigDecimal
理解BigDecimal
1、简介
Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。
2、构造器描述
BigDecimal(int) 创建一个具有参数所指定整数值的对象。
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。 //不推荐使用
BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。//推荐使用
3、方法描述
add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。
subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。
multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。
divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。
toString() 将BigDecimal对象的数值转换成字符串。
doubleValue() 将BigDecimal对象中的值以双精度数返回。
floatValue() 将BigDecimal对象中的值以单精度数返回。
longValue() 将BigDecimal对象中的值以长整数返回。
intValue() 将BigDecimal对象中的值以整数返回。
特别说明一下,为什么BigDecimal(double) 不推荐使用
Java解决精度问题
在进行浮点类数据计算的时候,浮点参与计算,会左移或右移n位,直到小数点移动到第一个有效数字的右边。于是11.9在转化为二进制后 小数点左移3位,就得到1. 011 11100110011001100110(精度丢失2)
于是最终浮点型运算出现了精度丢失误差。
解决方法:1.使用维护精度的二进制编码的十进制(BCD)库、
2.用String来构造BigDecimal。(BigDecimal是java.math.BigDecimal类)
@Slf4j @RunWith(SpringRunner.class) @SpringBootTest(classes = ReportApplication.class) public class PrecisionTest { //鼓励用BigDecimal解决精度问题 @Test public void test1() { Double a = 12.0; Double b = 11.9; System.out.println("last result:" + (a - b)); System.out.println("============="); ///we use BigDecimal for resolve precision; BigDecimal aMal = new BigDecimal(Double.toString(a)); BigDecimal bMal = new BigDecimal(Double.toString(b)); System.out.println("new result:" + aMal.subtract(bMal)); } }
=====================
加减乘除我们都可以用BigDecimal的自带的方法,在这基础上我们可以根据需要写各种各样的工具需要来适应我们的需求
public static String divideDouble(Double a, Double b) { String str = null; try { str = new BigDecimal(a).divide(new BigDecimal(b), 2, BigDecimal.ROUND_HALF_DOWN).toString(); } catch (Exception e) { e.printStackTrace(); } return str; } public static String subtractString(String a, String b) { String str = new BigDecimal(a).subtract(new BigDecimal(b)) .setScale(2, BigDecimal.ROUND_HALF_DOWN).toString(); return str; } public static String addString(String a, String b) { String str = new BigDecimal(a).add(new BigDecimal(b)) .setScale(2, BigDecimal.ROUND_HALF_DOWN).toString(); return str; } public static String subtractString(String a, String b) { String str = new BigDecimal(a).subtract(new BigDecimal(b)) .setScale(2, BigDecimal.ROUND_HALF_DOWN).toString(); return str; } public static String multiplyString(String a, String b) { String str = new BigDecimal(a).multiply(new BigDecimal(b)) .setScale(2, BigDecimal.ROUND_HALF_DOWN).toString(); return str; } public static String multiply(String a, String b) { String str = new BigDecimal(a).multiply(new BigDecimal(b)) .setScale(5, BigDecimal.ROUND_HALF_DOWN).toString(); return str; } public static String divideString(String a, String b) { if (StringUtils.isBlank(b)) { return null; } String str = new BigDecimal(a).divide(new BigDecimal(b), 2, BigDecimal.ROUND_HALF_DOWN).toString(); return str; } public static String addDouble(Double a, Double b) { String str = new BigDecimal(a).add(new BigDecimal(b)) .setScale(2, BigDecimal.ROUND_HALF_DOWN).toString(); return str; } public static String subtractDouble(Double a, Double b) { String str = new BigDecimal(a).subtract(new BigDecimal(b)) .setScale(2, BigDecimal.ROUND_HALF_DOWN).toString(); return str; } public static String multiplyDouble(Double a, Double b) { String str = new BigDecimal(a).multiply(new BigDecimal(b)) .setScale(2, BigDecimal.ROUND_HALF_DOWN).toString(); return str; } public static String divideDouble(Double a, Double b) { String str = null; try { str = new BigDecimal(a).divide(new BigDecimal(b), 2, BigDecimal.ROUND_HALF_DOWN).toString(); } catch (Exception e) { e.printStackTrace(); } return str; } public static Double addDoubleResult(Double a, Double b) { Double c = a + b; double three = getDoubleTwo(c); return three; } public static Double subtractDoubleResult(Double a, Double b) { Double c = a - b; double three = getDoubleTwo(c); return three; } public static Double multiplyDoubleResult(Double a, Double b) { Double c = a * b; double three = getDoubleTwo(c); return three; } public static double getDoubleTwo(Double c) { double one = c; BigDecimal two = new BigDecimal(one); return two.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); } public static Double divideDoubleResult(Double a, Double b) { if (0 == b) { return 0.0; } Double c = a / b; double three = getDoubleTwo(c); return three; } private String scientificCountingMethod(String a) { java.text.DecimalFormat nf = new java.text.DecimalFormat("00.00"); //.00表示小数点后面多少位 String format = nf.format(a); return format; }
以下做了优化包括加减乘除方法封装
@Slf4j @RunWith(SpringRunner.class) @SpringBootTest(classes = ReportApplication.class) public class PrecisionTest { //鼓励用BigDecimal解决精度问题 @Test public void test1() { Double a = 12.0; Double b = 11.9; System.out.println("last result:" + (a - b)); System.out.println("============="); ///we use BigDecimal for resolve precision; BigDecimal aMal = new BigDecimal(a.toString()); BigDecimal bMal = new BigDecimal(b.toString()); System.out.println("new result1:" + aMal.subtract(bMal)); } @Test public void test2() { System.out.println("result-------------"); System.out.println(add(0.05, 0.01).doubleValue()); System.out.println(sub(100.0, 2.04)); System.out.println(multiply(10.01, 22.2)); System.out.println(divide(2.2, 1.1)); } public static BigDecimal add(Double a, Double b) { BigDecimal add = new BigDecimal(a.toString()).add(new BigDecimal(b.toString())); return add; } public static BigDecimal sub(Double a, Double b) { return new BigDecimal(a.toString()).subtract(new BigDecimal(b.toString())); } public static BigDecimal multiply(Double a, Double b) { return new BigDecimal(a.toString()).multiply(new BigDecimal(b.toString())); } /** * 除法 * @param a * @param b * @return */ public static BigDecimal divide(Double a, Double b) { BigDecimal b1 = new BigDecimal(a.toString()); BigDecimal b2 = new BigDecimal(b.toString()); //这里是四舍五入 并且保留X位小数 默认两位 return b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP); } }