Math、BigDecimal、BigInteger的API总结和错误用法
Header
在代码的过程中,或多或少会用到MAth,BigDecimal,BigInteger等类来进行一些数学运算,但是其中有很多API不常用的话,很容易不太回忆,那么就对这些API总结一下,同时,也会对在使用这些API的过程中,一些出现过的问题也会持续更新的。
目录
Body
Math
API | 参数 | 返回值 | 说明 |
Math.E | 无 | double | 比任何其他值都更接近e(自然对数的底数)的double值 |
Math.PI | 无 | double | 比任何其他值都更接近 pi(即圆的周长与直径之比)的 double 值 |
Math.abs() | int | long | float | double | int | long | float | double | 对各种数据类型求绝对值 |
Math.cos() | double | double | 求余弦值 |
Math.sin() | double | double | 求正弦值 |
Math.tan() | double | double | 求正切值 |
Math.acos() | double | double | 求反余弦值 |
Math.asin() | double | double | 求反正弦值 |
Math.atan() | double | double | 求反正切值 |
Math.atan2() | double(x) & double(y) | double | 求向量(x,y)与x轴的夹角 |
Math.cbrt() | double | double | 求立方根 |
Math.sqrt() | double | double | 求平方根 |
Math.max() |
int & int | long & long | float & float | double & double |
int | long | float | double | 求两数中的最大值 |
Math.min() |
int & int | long & long | float & float | double & double |
int | long | float | double | 求两数中的最小值 |
Math.log() | double | double | 求自然对数(底数为e) |
Math.log10() | double | double | 求底数为10的对数 |
Math.log1p() | double(x) | double | 求x + 1的自然对数 |
注:对数运算函数只能传double型数据并返回double型数据,不能重载 | |||
Math.exp() | double(x) | double |
求e^x的值 |
Math.expm1() | double(x) | double | 求e^x - 1的值 |
Math.pow() | double (x) & double (y) | double | 求 x^ y的值 |
Math.random() | 无 | double | 返回(0.0~1.0)之间的double值 |
Math.toDegrees() | double | double | 弧度换角度 |
Math.toRadians() | double | double | 角度换弧度 |
Math.ceil() | double (x) | double | 返回大于x的第一个整数所对应的浮点数(值是整数,但类型是浮点型) |
Math.floor() | double (x) | double | 返回小于x的第一个整数所对应的浮点数(值是整数,但类型是浮点型) |
Math.rint() | double (x) | double | 返回最接近x的整数的double |
我们可以看到Math类的构造函数是私有的,因为在面向对象中类是抽象的而对象是具体的,由于数学本身是抽象的没办法具体,所以Math类不能实例化为对象。
BigDecimal
先说下BigDecimal的setScale()吧
API | 说明 |
setScale(1) | 表示保留一位小数,默认使用四舍五入方式 |
setScale(1,BigDecimal.ROUND_DOWN) |
直接删除多余的小数位,如2.35变为2.3 向零方向舍入的舍入模式 |
setScale(1,BigDicimal.ROUND_UP) |
进位处理,2.35变为2.4 远离零方向舍入的舍入模式 |
setScale(1,BigDecimal.ROUND_HALF_UP) |
四舍五入,2.35变为2.4 向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入 |
setScale(1,BigDecimal.ROUND_HALF_DOWN) |
四舍五入,2.35变为2.3,如果是5则向下舍去 向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入 |
setScale(1,BigDecimal.ROUND_CEILING) | 向正无限大方向舍入的舍入模式 |
setScale(1,BigDecimal.ROUND_FLOOR) | 向负无限大方向舍入的舍入模式 |
setScale(1,BigDecimal.ROUND_UNNECESSARY) | 用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。(默认模式) |
(下面注释的这几点摘自https://blog.csdn.net/ahwr24/article/details/7048724)
注释:
1:
scale指的是你小数点后的位数。比如123.456则score就是3.
score()就是BigDecimal类中的方法啊。
比如:BigDecimal b = new BigDecimal("123.456");
b.scale(),返回的就是3.
2:
roundingMode是小数的保留模式。它们都是BigDecimal中的常量字段,有很多种。
比如:BigDecimal.ROUND_HALF_UP表示的就是4舍5入。
3:
pubilc BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
的意思是说:我用一个BigDecimal对象除以divisor后的结果,并且要求这个结果保留有scale个小数位,roundingMode表示的就是保留模式是什么,是四舍五入啊还是其它的,你可以自己选!
4:对于一般add、subtract、multiply方法的小数位格式化如下:
BigDecimal mData = new BigDecimal("9.655").setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("mData=" + mData);
----结果:----- mData=9.66
API | 参数 | 返回值 | 说明 |
new BigDecimal(double d) | double | BigDecimal | 以double值来创建一个BigDecimal对象 |
new BigDecimal(String s) | String | BigDecimal | 以String值来创建一个BigDecimal对象 |
注意: 1、参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。 2、另一方面,String 构造方法是完全可预知的:写入 newBigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用String构造方法。 3、当double必须用作BigDecimal的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用Double.toString(double)方法,然后使用BigDecimal(String)构造方法,将double转换为String。要获取该结果,请使用static valueOf(double)方法 |
|||
add() | BigDecimal | BigDecimal | 加法操作 |
subtract() | BigDecimal | BigDecimal | 减法操作 |
multiply() | BigDecimal | BigDecimal | 乘法操作 |
divide() | BigDecimal | BigDecimal | 除法操作 |
intValue() |
无 | int | 输出值的int型 |
doubleValue() | 无 | double | 输出值的double型 |
floatValue() | 无 | float | 输出值的float型 |
longValue() | 无 | long | 输出值的long型 |
其中,在使用BigDecimal的过程中会碰到很多问题,我这里也遇到过一些问题,但是就不一一敲了,给几个遇到过的问题的链接看看吧。
BigDecimal的double入参的构造函数导致的数据损失精度问题
BigDecimal不可变类型以及除法抛ArithmeticException:Non-terminating decimal expansion问题
BigInteger
API | 参数 | 返回值 | 说明 |
new BigInteger(String s) | String | BigInteger | 将十进制字符串转化为BigInteger |
new BigInteger(byte[] b) | byte[] | BigInteger | 具体理解请点击这里 |
new BigInteger(String s,int radix) | String & int | BigInteger | 将radix进制的字符串转化为BigInteger |
new BigInteger(int numBits,Random rnd) | int & Random | BigInteger | 随机生成0到2的numBits次方 - 1的随机数 |
new BigInteger(int signum,byte[] magnitude) | int & byte[] | BigInteger | signum为符号位,1为正,0为0,-1为负 |
new BigInteger(int bitLength,int certainty,Random rnd) | int & int & Random | BigInteger | 随机生成一个 长度为bitLength的 可能性大于(1-1/(2的certainty次方))是素数 的数 |
BigInteger.ZERO | 无 | BigInteger | 0常量 |
BigInteger.ONE | 无 | BigInteger | 1常量 |
BigInteger.TEN | 无 | BigInteger | 10常量 |
BigInteger.valueOf() |
long (x) |
BigInteger | 值等于x的BigInteger |
add() | BigInteger | BigInteger | 加法 |
subtract() | BigInteger | BigInteger | 减法 |
multiply() | BigInteger | BigInteger | 乘法 |
divide() | BigInteger | BigInteger | 除法 |
mod() | BigInteger | BigInteger | a.mod(b) 取模a%b b需大于0 5mod3=2 -5mod3=1 |
remainder() | BigInteger | BigInteger | a.remainder(b) 求余 5rem3=2 -5rem3=-2 5rem-3=2 |
divideAndRemainder() | BigInteger | BigInteger[] | a.divideAndRemainder(b) [0]为a/b [1]为a%b |
equals() | BigInteger | boolean | a.equals(b) a==b? |
signum() | 无 | int | a.signum() a的正负 正为1 0为0 负为-1 |
ads() | 无 | BigInteger | a.abs() 绝对值|a| |
compareTo() | BigInteger | BigInteger | a.compareTo(b) 比较a>b返回1 a==b返回0 a<b返回-1 |
negate() | 无 | BigInteger | a.negate() 相反数-a |
max() | BigInteger | BigInteger | a.max(b) max(a,b) |
min() | BigInteger | BigInteger | a.min(b) min(a,b) |
pow() | int | BigInteger | a.pow(3) a的3次方 |
...还有不少,不过用的不多 |
其实,BigInteger 和BigDecimal有一些类似的地方,比如不可变类型等等
再有新问题再更新吧
End
由于最近在看算法,会用到很多这三个类的api,而自己去打开类看吧,麻烦,去网上搜,也麻烦,不如自己总结一下,加上遇到的问题,也算是做个笔记,如果有经常用到这些类的api的同志们,希望能帮助到你们。