08. 详解 Math 类以及大数运算
java.lang.Math(final 类)
Java 语言是彻底地面向对象语言,哪怕是进行数学运算也封装到一个类中的,这个类是 java.lang.Math,Math 类是 final 的不能被继承。Math 类中包含用于进行基本数学运算的方法,如指数、对数、平方根和三角函数等。这些方法分类如下:
1. 舍入方法
static double ceil(double a)
:返回大于或等于 a 最小整数。static double floor(double a)
:返回小于或等于 a 最大整数。static int round(float a)
:四舍五入方法。
2. 最大值和最小值
static int min(int a, int b)
:取两个 int 整数中较小的一个整数。static int min(long a, long b)
:取两个 long 整数中较小的一个整数。static int min(float a, float b)
:取两个 float 浮点数中较小的一个浮点数。static int min(double a, double b)
:取两个 double 浮点数中较小的一个浮点数。
max 方法取两个数中较大的一个数,max 方法与 min 方法参数类似也有 4 个版本,这里不再赘述。
3. 绝对值
static int abs(int a)
:取 int 整数 a 的绝对值。static long abs(long a)
:取 long 整数 a 的绝对值。static float abs(float a)
:取 float 浮点数 a 的绝对值。static double abs(double a)
:取 double 浮点数 a 的绝对值。
4. 三角函数:
static double sin(double a)
:返回角的三角正弦。static double cos(double a)
:返回角的三角余弦。static double tan(double a)
:返回角的三角正切。static double asin(double a)
:返回一个值的反正弦。static double acos(double a)
:返回一个值的反余弦。static double atan(double a)
:返回一个值的反正切。static double toDegrees(double angrad)
:将弧度转换为角度。static double toRadians(double angdeg)
:将角度转换为弧度。
5. 对数运算:static double log(double a)`,返回a的自然对数。
6. 平方根:static double sqrt(double a)`,返回a的正平方根。
7. 幂运算:static double pow(double a, double b)`,返回第一个参数的第二个参数次幂的值。
8. 计算随机值:static double random(),返回大于等于 0.0 且小于 1.0随机数(左闭右开))。
9. 常量
圆周率PI,自然对数的底数E。
大数值
对货币等大值数据进行计算时,int、long、float 和 double 等基本数据类型已经在精度方面不能满足需求了。为此 Java 提高了两个大数值类:BigInteger 和 BigDecimal,这里两个类都继承自 Number 抽象类。
BigInteger
java.math.BigInteger 是不可变的任意精度的大整数。BigInteger 构造方法有很多,其中字符串参数的构造方法有两个:
- BigInteger(String val):将十进制字符串val转换为 BigInteger 对象。
- BigInteger(String val, int radix):按照指定基数 radix 将字符串 val 转换为 BigInteger 对象。
BigInteger 提供多种方法,下面列举几个常用的方法:
int compareTo(BigInteger val):将当前对象与参数 val 进行比较,方法返回值是 int,如果返回值是 0,则相等;如果返回值小于 0,则此对象小于参数对象;如果返回值大于 0,则此对象大于参数对象。
- BigInteger add(BigInteger val):加运算,当前对象数值加参数val。
- BigInteger subtract(BigInteger val):减运算,当前对象数值减参数val。
- BigInteger multiply(BigInteger val):乘运算,当前对象数值乘参数val。
- BigInteger divide(BigInteger val):除运算,当前对象数值除以参数val。
BigDecimal
java.math.BigDecimal 是不可变的任意精度的有符号十进制数。BigDecimal构造方法有很多:
- BigDecimal(BigInteger val):将 BigInteger 对象 val 转换为BigDecimal对象。
- BigDecimal(double val):将 double 转换为BigDecimal对象,参数val是double类型的二进制浮点值准确的十进制表示形式。
- BigDecimal(int val):将int转换为 BigDecimal 对象。
- BigDecimal(long val):将long转换为 BigDecimal 对象。
- BigDecimal(String val):将字符串表示数值形式转换为 BigDecimal 对象。
BigDecimal 提供多种方法,下面列举几个常用的方法:
- int compareTo(BigDecimal val):将当前对象与参数 val 进行比较,方法返回值是 int,如果返回值是0,则相等;如果返回值小于 0,则此对象小于参数对象;如果返回值大于0,则此对象大于参数对象。
- BigDecimal add(BigDecimal val):加运算,当前对象数值加参数 val。
- BigDecimal subtract(BigDecimal val):减运算,当前对象数值减参数 val。
- BigDecimal multiply(BigDecimal val):乘运算,当前对象数值乘参数 val。
- BigDecimal divide(BigDecimal val):除运算,当前对象数值除以参数 val。
- BigDecimal divide(BigDecimal val, int roundingMode):除运算,当前对象数值除以参数 val。roundingMode 要应用的舍入模式。
注意:如果传入的字符串是一个非法的数值,例如空串、含有字母,这时候就会报异常 NumberFormatException
1 | new BigDecimal(""); |
都会报这个 NumberFormatException。
RoundingMode 枚举介绍
1. ROUND_DOWN
1 | BigDecimal b = new BigDecimal("2.225667").setScale(2, BigDecimal.ROUND_DOWN); |
2. ROUND_UP
1 | BigDecimal c = new BigDecimal("2.224667").setScale(2, BigDecimal.ROUND_UP); |
3. ROUND_CEILING
1 | BigDecimal f = new BigDecimal("2.224667").setScale(2, BigDecimal.ROUND_CEILING); |
5. ROUND_HALF_UP - 这是标准的四舍五入。
1 | BigDecimal d = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_UP); |
6. ROUND_HALF_DOWN
1 | BigDecimal e = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_DOWN); |
7. ROUND_HALF_EVEN
1 | BigDecimal j = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_EVEN); |
8.ROUND_UNNECESSARY
1 | BigDecimal l = new BigDecimal("2.215").setScale(3, BigDecimal.ROUND_UNNECESSARY); |
IDEA 更推荐使用 public BigDecimal setScale(int newScale, RoundingMode roundingMode)
,而非第二个参数传入的是 int 类型的入参。
使用 BigDecimal 总结
- BigDecimal的初始化要使用 String 入参或 BigDecimal.valueOf()。不能使用 double 和 float。因为 double 和 float 本身的存储可能不精确。
- 比较两个BigDecimal的 value 要使用 compareTo。
数据库数据类型decimal理解
MySQL DECIMAL
数据类型用于在数据库中存储精确的数值。
例如语法:column_name DECIMAL(P, D)
其中 P 表示的是有效数字的位数,D 表示是小数的位数,D 小于或等于P。
理解可看下面代码:
1 | create table decimal_test( |
- 整数的位数必须小于等于 m-d,不然报错。小数的位数可以大于 d 位。多出 d 位时会做四舍五入,截取到d位。
- 以上均不包括小数点、符号的位数。数字的总长度是 m 位,保存后的小数位最多是 d 位。如果保存后是整数,小数位不会补 0。
1 | select * from decimal_test; |
数值格式化
我们经常要将数字进行格式化,比如取 2 位小数,这是最常见的。Java 提供 DecimalFormat 类,帮你用最快的速度将数字格式化为你需要的样子。下面是常用的例子:
1 | import java.text.DecimalFormat; |
DecimalFormat 类主要靠 # 和 0 两种占位符号来指定数字长度。0 表示如果位数不足则以 0 填充,# 表示只要有可能就把数字拉上这个位置。上面的例子包含了差不多所有的基本用法,如果你想了解更多,请参考 DecimalFormat 类的文档。
数据类型转换的小结
取小于等于该数组的数(取整)
int i = (int)12.34;
int j = Math.round(12.34)
int 转 char
char c = (char)c;
字符串转 int 出错会抛 java.lang.NumberFormatException 运行时异常
int i=Integer.parseInt(s);
int 转字符串
String s = String.valueOf(i);
四舍五入
Math.round()
三目运算符的一个坑-自动拆箱
1 | Integer a = null ; |
开发中避免的措施:
- 对对象进行使用或者操作时都先验空,然后再进行操作处理。
- 三目运算符后最好使用同种类型的对象。
参考
- 【java】BigDecimal.setScale 用法总结 - Angel 挤一挤 - 博客园 https://www.cnblogs.com/sxdcgaq8080/p/12123917.html
- 数据库数据类型 decimal 理解 - 学无止境 BS - 博客园 https://www.cnblogs.com/chenweipeng/p/9627659.html