java.math.BigDecimal
Java,java.math包中提供的API类:BigDecimal,用于对超过16位有效位的数进行精确的运算;
虽然,双精度浮点型变量double可以处理16位有效数,但在实际应用中,需要对更大或者更小的数进行运算和处理,又float、double存在的精度问题,BigDecimal更准确。float和double只能用来做科学计算或者是工程计算,而在商业计算中推荐使用BigDecimal;
BigDecimal,不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。
注:double在内存中使用双精度浮点数存储和表示,双精度浮点数采用:IEEE 754标准,这个标准是一个二进制的浮点计数法,从原理上无法精确表示十进制的大部分小数。
MySQL数据库=>decimal类型
MySQL中的decimal类型:
decimal(18,2) ,18是定点精度,2是小数位数。
decimal(a,b) ,a指定指定小数点左边和右边可以存储的十进制数字的最大个数,最大精度38;b指定小数点右边可以存储的十进制数字的最大个数,小数位数必须是从0到a之间的值,默认小数位数是0。
MySQL中使用decimal类型:
`account_balance` DECIMAL(10,2) NULL DEFAULT '0.00' COMMENT '账户余额'
浮点型:float、double的精度问题
/** * 精度问题 */public class PrecisionLossDemo { public static void main(String[] args) { // 使用double类型的数据进行运算时结果是不准确的 System.out.println(0.05F + 0.01F); // 输出: 0.060000002 System.out.println(0.05 + 0.01); // 输出: 0.060000000000000005 System.out.println(1.0 - 0.42); // 输出: 0.5800000000000001 System.out.println(4.015 * 100); // 输出: 401.49999999999994 System.out.println(123.3 / 100); // 输出: 1.2329999999999999 }}
BigDecimal类的使用(基本操作)
import java.math.BigDecimal;import java.text.NumberFormat;public class BigDecimalApplyDemo { /** * 基本应用 */ public static void baseUse() { BigDecimal number01 = new BigDecimal("0.01"); System.out.println("BigDecimal==>String," + number01.toString()); System.out.println("BigDecimal==>BigInteger," + number01.toBigInteger()); BigDecimal number02 = new BigDecimal("0.02"); System.out.println("BigDecimal==>加法," + number01.add(number02)); System.out.println("BigDecimal==>减法," + number01.subtract(number02)); System.out.println("BigDecimal==>乘法," + number01.multiply(number02)); System.out.println("BigDecimal==>除法," + number01.divide(number02)); // 0 BigDecimal number03 = BigDecimal.ZERO; System.out.println("BigDecimal==>String," + number03.toString()); // 正数 BigDecimal number04 = BigDecimal.valueOf(0.03); System.out.println("BigDecimal==>String," + number04.toString()); // 负数 BigDecimal number05 = BigDecimal.valueOf(-0.04); System.out.println("BigDecimal==>String," + number05.toString()); } /** * 格式化 */ public static void formatUse() { BigDecimal number11 = BigDecimal.valueOf(3.1415926); // 进位处理 BigDecimal number111 = number11.setScale(3, BigDecimal.ROUND_UP); System.out.println("BigDecimal==>String," + number111.toString()); // 四舍五入(碰5不舍),保留3位小数 BigDecimal number112 = number11.setScale(3, BigDecimal.ROUND_HALF_UP); System.out.println("BigDecimal==>String," + number112.toString()); // 四舍五入(碰5舍弃),保留3位小数 BigDecimal number113 = number11.setScale(3, BigDecimal.ROUND_HALF_DOWN); System.out.println("BigDecimal==>String," + number113.toString()); // 直接删除多余的小数位 BigDecimal number114 = number11.setScale(3, BigDecimal.ROUND_DOWN); System.out.println("BigDecimal==>String," + number114.toString()); } /** * 类型转换 */ public static void transforUse() { Float num1 = 13.846154f; BigDecimal number21 = new BigDecimal(Float.toString(num1)); BigDecimal number22 = new BigDecimal("2.0").add(number21); System.out.println("BigDecimal==>String," + number22.toString()); Float num12 = Float.parseFloat(number22.toString()); System.out.println("Float," + num12); double num2 = 13.846154; BigDecimal number23 = new BigDecimal(String.valueOf(num2)); System.out.println("BigDecimal==>String," + number23.toString()); double num22 = Double.parseDouble(number23.toString()); System.out.println("double," + num22); } /** * 比较 */ public static void compareUse() { BigDecimal a = BigDecimal.valueOf(1.1); BigDecimal b = BigDecimal.valueOf(1.2); //前提为a、b均不能为null if(a.compareTo(b) == -1){ System.out.println("比较:a小于b"); } b = BigDecimal.valueOf(1.1); if(a.compareTo(b) == 0){ System.out.println("比较:a等于b"); } b = BigDecimal.valueOf(1.0); if(a.compareTo(b) == 1){ System.out.println("比较:a大于b"); } b = BigDecimal.valueOf(1.1); if(a.compareTo(b) > -1){ System.out.println("比较:a大于等于b"); } b = BigDecimal.valueOf(1.1); if(a.compareTo(b) < 1){ System.out.println("比较:a小于等于b"); } } public static void otherUse() { double d = 9.84; double d2 = 1.22; //注意需要使用BigDecimal(String val)构造方法 BigDecimal bigDecimal = new BigDecimal(Double.toString(d)); BigDecimal bigDecimal2 = new BigDecimal(Double.toString(d2)); System.out.println("bigDecimal=" + bigDecimal); System.out.println("bigDecimal2=" + bigDecimal2); //加法 BigDecimal bigDecimalAdd = bigDecimal.add(bigDecimal2); double add = bigDecimalAdd.doubleValue(); System.out.println("add=" + add); //减法 BigDecimal bigDecimalSubtract = bigDecimal.subtract(bigDecimal2); double subtract = bigDecimalSubtract.doubleValue(); System.out.println("subtract=" + subtract); //乘法 BigDecimal bigDecimalMultiply = bigDecimal.multiply(bigDecimal2); double multiply = bigDecimalMultiply.doubleValue(); System.out.println("multiply=" + multiply); //除法 int scale = 2;//保留2位小数 BigDecimal bigDecimalDivide = bigDecimal.divide(bigDecimal2, scale, BigDecimal.ROUND_HALF_UP); double divide = bigDecimalDivide.doubleValue(); System.out.println("divide=" + divide); //格式化 double format = 12343171.6; //获取常规数值格式 NumberFormat number = NumberFormat.getNumberInstance(); String str = number.format(format);//12,343,171.6 System.out.println("格式化,str=" + str); //获取整数数值格式 NumberFormat integer = NumberFormat.getIntegerInstance(); str = integer.format(format);//如果带小数会四舍五入到整数12,343,172 System.out.println("格式化,str=" + str); //获取货币数值格式 NumberFormat currency = NumberFormat.getCurrencyInstance(); currency.setMinimumFractionDigits(2);//设置数的小数部分所允许的最小位数(如果不足后面补0) currency.setMaximumFractionDigits(4);//设置数的小数部分所允许的最大位数(如果超过会四舍五入) str = currency.format(format);//¥12,343,171.60 System.out.println("格式化,str=" + str); //获取显示百分比的格式 NumberFormat percent = NumberFormat.getPercentInstance(); percent.setMinimumFractionDigits(2);//设置数的小数部分所允许的最小位数(如果不足后面补0) percent.setMaximumFractionDigits(3);//设置数的小数部分所允许的最大位数(如果超过会四舍五入) str = percent.format(format);//1,234,317,160.00% System.out.println("格式化,str=" + str); } public static void main(String[] args) { baseUse(); formatUse(); transforUse(); compareUse(); otherUse(); }}
Java BigDecimal<==>MySQL decimal(10,2)应用案例
CREATE TABLE `apply_financial_account` ( `id` BIGINT(11) NOT NULL AUTO_INCREMENT COMMENT '菜单ID' primary key, `user_id` INT(11) NULL DEFAULT NULL COMMENT '用户id', `username` VARCHAR(60) NOT NULL UNIQUE COMMENT '登录用户名', `real_name` VARCHAR(60) NOT NULL UNIQUE COMMENT '用户真实名称', `account_balance` decimal(10,2) DEFAULT '0.00' COMMENT '账户余额', `lock_version` INT(12) DEFAULT 1 COMMENT '锁--版本号', `operate_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '操作时间')COMMENT='财务账户表(使用)',ENGINE=InnoDB;
import java.math.BigDecimal;import java.sql.*;public class BigDecimalJDBCDemo { /** * @param connection */ public static void insert(Connection connection){ PreparedStatement pstat = null; try { StringBuilder sqlBuilder = new StringBuilder(); sqlBuilder.append("insert into `apply_financial_account`(`user_id`,`username`,`real_name`,`account_balance`,`lock_version`,`operate_time`)"); sqlBuilder.append(" "); sqlBuilder.append("value(?,?,?,?,?,?)"); // 创建PreparedStatement pstat = connection.prepareStatement(sqlBuilder.toString()); // user_id=1001 pstat.setInt(1,1001); // username=bailixi pstat.setString(2, "bailixi"); // real_name = "百里奚" pstat.setString(3, "百里奚"); // account_balance = new BigDecimal("1.23") pstat.setBigDecimal(4,new BigDecimal("1.23")); // lock_version = 1 pstat.setInt(5,1); // operate_time=当前时间 pstat.setTimestamp(6, new Timestamp(System.currentTimeMillis())); // // 执行 pstat.execute(); // 处理返回结果(这里无结果) } catch (SQLException e) { e.printStackTrace(); }finally { JDBCHelper.close(pstat); } } public static void main(String[] args) { Connection connection = JDBCHelper.createConnection(); insert(connection); JDBCHelper.close(connection); }}
import java.sql.*;public class JDBCHelper { /** * 创建连接 * * @param driverClass * @param url * @param user * @param password * @return */ public static Connection createConnection(String driverClass, String url, String user, String password) { Connection connection = null; try { Class.forName(driverClass); connection = DriverManager.getConnection(url, user, password); } catch (Exception e) { e.printStackTrace(); } return connection; } /** * @param resultSet */ public static void close(ResultSet resultSet) { if (resultSet != null) { try { resultSet.close(); } catch (SQLException e) { e.printStackTrace(); } resultSet = null; } } /** * @param statement */ public static void close(Statement statement) { if (statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } statement = null; } } /** * @param connection */ public static void close(Connection connection) { if (connection != null) { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } connection = null; } } /** * @return */ public static Connection createConnection() { String driverClass = "com.mysql.jdbc.Driver"; String url = "jdbc:mysql://127.0.0.1:3306/demo?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&allowMultiQueries=true&serverTimezone=GMT%2B8"; String user = "root"; String password = "root"; return createConnection(driverClass, url, user, password); } /** * @param args */ public static void main(String[] args) { System.out.println(createConnection()); }}