17.常用工具类,BigInteger和BigDecimal大整数与大浮点数(不限制位数)

 来自 

Java教程 - 廖雪峰的官方网站研究互联网产品和技术,提供原创中文精品教程https://www.liaoxuefeng.com/wiki/1252599548343744

但有缩减增加

1.常用工具类Math(+-*/)、随机数

进制转换等等

数字与字符串相互转换,进制相互转换,浮点型为什么会丢失精度(打印浮点型数字与预期不一致)_computer408的博客-CSDN博客1字符串转数字String s = "123";byte b = Byte.parseByte(s);short t = Short.parseShort(s);int i = Integer.parseInt(s);long l = Long.parseLong(s);Float f = Float.parseFloat(s);Double d = Double.parseDouble(s);boolean bo = Boolean.parseBoolean(s);char c =https://blog.csdn.net/computer408/article/details/122623630

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Random;

/**
* @Title
* @Author Eastlin
* @Description:
*/
public class BaseComputeTest {
public static void main(String[] args) {
//求绝对值,+-*/
Math.abs(-100); // 100
Math.abs(-7.8); // 7.8
int m=Math.addExact(1,3);//4
Math.subtractExact(3,1);//2
Math.multiplyExact(2,3);//6
Math.floorDiv(5,2);//2向下取整
Math.decrementExact(9);//8,减1操作
//取最大或最小值
Math.max(100, 99); // 100
Math.min(1.2, 2.3); // 1.2
//计算xy次方
Math.pow(2, 10); // 2的10次方=1024
//计算√x
Math.sqrt(2); // 1.414...
//计算ex次方
Math.exp(2); // 7.389...
//计算以e为底的对数:
Math.log(4); // 1.386...
//计算以10为底的对数:
Math.log10(100); // 2
//三角函数
Math.sin(3.14); // 0.00159...
Math.cos(3.14); // -0.9999...
Math.tan(3.14); // -0.0015...
Math.asin(1.0); // 1.57079...
Math.acos(1.0); // 0.0
//Math还提供了几个数学常量
double pi = Math.PI; // 3.14159...
double e_1 = Math.E; // 2.7182818...
Math.sin(Math.PI / 6); // sin(π/6) = 0.5
//生成一个随机数x,x的范围是0 <= x < 1,左闭右开是原则
Math.random(); // 0.53907... 每次都不一样
//可理解为百分数使用
double x = Math.random(); // x的范围是[0,1)
double min = 10;
double max = 50;
double y = x * (max - min) + min; // y的范围是[10,50)
long n = (long) y; // n的范围是[10,50)的整数
System.out.println(y);
System.out.println(n);
//Random伪随机数,与Scanner类似用法,都是util包下的
Random r = new Random();
r.nextInt(); // -1468439593,每次都不一样
r.nextInt(10); // 5,生成一个[0,10)之间的int
r.nextLong(); // 8811649292570369305,每次都不一样
r.nextFloat(); // 0.54335...生成一个[0,1)之间的float
r.nextDouble(); // 0.3716...生成一个[0,1)之间的double
SecureRandom sr = new SecureRandom();
System.out.println(sr.nextInt(100));

//真随机数
SecureRandom sr1 = new SecureRandom();
System.out.println(sr1.nextInt(100));
SecureRandom sr2 = null;
try {
sr2 = SecureRandom.getInstanceStrong(); // 获取高强度安全随机数生成器
} catch (NoSuchAlgorithmException e) {
sr2 = new SecureRandom(); // 获取普通的安全随机数生成器
}
byte[] buffer = new byte[16];
sr.nextBytes(buffer); // 用安全随机数填充buffer
System.out.println(Arrays.toString(buffer));
}
}

Random用来创建伪随机数。所谓伪随机数,是指只要给定一个初始的种子,产生的随机数序列是完全一样的。要生成一个随机数,可以使用nextInt()、nextLong()、nextFloat()、nextDouble()

创建Random实例时,如果不给定种子,就使用系统当前时间戳作为种子,因此每次运行时,种子不同,得到的伪随机数序列就不同。种子即参数

SecureRandom

有伪随机数,就有真随机数。实际上真正的真随机数只能通过量子力学原理来获取,而我们想要的是一个不可预测的安全的随机数,SecureRandom就是用来创建安全的随机数的
SecureRandom的安全性是通过操作系统提供的安全的随机种子来生成随机数。这个种子是通过CPU的热噪声、读写磁盘的字节、网络流量等各种随机事件产生的“熵”。
在密码学中,安全的随机数非常重要。如果使用不安全的伪随机数,所有加密体系都将被攻破。因此,时刻牢记必须使用SecureRandom来产生安全的随机数。

需要使用安全随机数的时候,必须使用SecureRandom,绝不能使用Random!
小结

Java提供的常用工具类有:

  • Math:数学计算
  • Random:生成伪随机数
  • SecureRandom:生成安全的随机数

2.BigInteger

java.math.BigInteger就是用来表示任意大小的整数,即bit位数不限制。

我们平时用的基本数据类型都是有位数限制的,最长的是long和double为64位。long型整数运算比,BigInteger不会有范围限制,但缺点是速度比较慢。

BigInteger运算(必须先构造实例,再用jdk提供的方法)

1.1基本运算 Big1.XX(Big2)

BigInteger bi = new BigInteger("2");
BigInteger bj = new BigInteger("26");
//bi.add(),bi.subtract() bi.multiply(),bi.divide(),bi.pow()+-*/^
System.out.println(bj.subtract(bi));//24
System.out.println(bi.pow(5));//32

1.2转换

可以把BigInteger转换成long型:使用longValueExact()方法时,如果超出了long型的范围,会抛出ArithmeticException。

BigInteger和Integer、Long一样,也是不可变类,并且也继承自Number类。因为Number定义了转换为基本类型的几个方法:

  • 转换为byte:byteValue()
  • 转换为short:shortValue()
  • 转换为int:intValue()
  • 转换为long:longValue()
  • 转换为float:floatValue()
  • 转换为double:doubleValue()

BigInteger表示的范围超过了基本类型的范围,转换时将丢失高位信息,即结果不一定是准确的。如果需要准确地转换成基本类型,可以使用

intValueExact()、longValueExact()等方法,在转换时如果超出范围,将直接抛出ArithmeticException异常。

如果BigInteger的值甚至超过了float的最大范围(3.4x1038),那么返回的float是什么呢?Infinity 

BigInteger i = new BigInteger("123456789000");
System.out.println(i.longValue()); // 123456789000
//System.out.println(i.multiply(i).longValueExact()); // java.lang.ArithmeticException: BigInteger out of long range
BigInteger n = new BigInteger("999999").pow(99);
float f = n.floatValue();
System.out.println(f);//Infinity

1.3特征

BigInteger用于表示任意大小的整数;

BigInteger是不变类,并且继承自Number;

将BigInteger转换成基本类型时可使用longValueExact()等方法保证结果准确。

进制转换的内容为底层实现方式

3.BigDecimal

和BigInteger类似,BigDecimal可以表示一个任意大小且精度完全准确的浮点数。

BigDecimal bd = new BigDecimal("123.4567");
//+-*/^同BigInteger
System.out.println(bd.multiply(bd)); // 15241.55677489
//scale()获取小数位数<=0表示整数
BigDecimal d1 = new BigDecimal("123.45");
BigDecimal d2 = new BigDecimal("123.4500");
BigDecimal d3 = new BigDecimal("1234500");
System.out.println(d1.scale()); // 2,两位小数
System.out.println(d2.scale()); // 4
System.out.println(d3.scale()); // 0
//去冗余(表示冗余)0
BigDecimal d4 = d2.stripTrailingZeros();
System.out.println(d2.scale()); // 4
System.out.println(d4.scale()); // 2,因为去掉了00
BigDecimal d5 = d3.stripTrailingZeros();
System.out.println(d3.scale()); // 0
System.out.println(d5.scale()); // -2,表示这个数是个整数,并且末尾有2个0

BigDecimal的stripTrailingZeros()方法,可以将一个BigDecimal格式化为一个相等的,但去掉了末尾0的BigDecimal:

比较BigDecimal


在比较两个BigDecimal的值是否相等时,要特别注意,使用equals()方法不但要求两个BigDecimal的值相等,还要求它们的scale()相等:
必须使用compareTo()方法来比较,它根据两个值的大小分别返回负数、正数和0,分别表示小于、大于和等于。
总是使用compareTo()比较两个BigDecimal的值,不要使用equals()!
如果查看BigDecimal的源码,可以发现,实际上一个BigDecimal是通过一个BigInteger和一个scale来表示的,即BigInteger表示一个完整的整数,而scale表示小数位数:

BigDecimal bd = new BigDecimal("123.4567");
//+-*/^同BigInteger
System.out.println(bd.multiply(bd)); // 15241.55677489
//scale()获取小数位数<=0表示整数
BigDecimal d1 = new BigDecimal("123.45");
BigDecimal d2 = new BigDecimal("123.4500");
BigDecimal d3 = new BigDecimal("1234500");
System.out.println(d1.scale()); // 2,两位小数
System.out.println(d2.scale()); // 4
System.out.println(d3.scale()); // 0
//去冗余(表示冗余)0
BigDecimal d4 = d2.stripTrailingZeros();
System.out.println(d2.scale()); // 4
System.out.println(d4.scale()); // 2,因为去掉了00
BigDecimal d5 = d3.stripTrailingZeros();
System.out.println(d3.scale()); // 0
System.out.println(d5.scale()); // -2,表示这个数是个整数,并且末尾有2个0


BigDecimal d_1 = new BigDecimal("123.456789");
BigDecimal d6= d_1.setScale(4, RoundingMode.HALF_UP); // 四舍五入,123.4568
BigDecimal d7 = d_1.setScale(4, RoundingMode.DOWN); // 直接截断,123.4567
System.out.println(d6);
System.out.println(d7);
//对BigDecimal做加、减、乘时,精度不会丢失,但是做除法时,存在无法除尽的情况,这时,就必须指定精度以及如何进行截断
BigDecimal d8 = new BigDecimal("123.456");
BigDecimal d9 = new BigDecimal("23.456789");
BigDecimal d89 = d8.divide(d9, 10, RoundingMode.HALF_UP); // 保留10位小数并四舍五入
BigDecimal d891 = d8.divide(d9); // 报错:ArithmeticException,因为除不尽

BigDecimal n1 = new BigDecimal("12.345");
BigDecimal m = new BigDecimal("0.12");
BigDecimal[] dr = n1.divideAndRemainder(m);
System.out.println(dr[0]); // 102
System.out.println(dr[1]); // 0.105
//商总是整数,余数不会大于除数
if (dr[1].signum() == 0) {//余数为0
// n是m的整数倍
}
//比较BigDecimal,用compareTo才是比较值
BigDecimal d10 = new BigDecimal("123.456");
BigDecimal d11 = new BigDecimal("123.45600");
System.out.println(d10.equals(d11)); // false,因为scale不同
System.out.println(d10.equals(d11.stripTrailingZeros())); // true,因为d2去除尾部0后scale变为2
System.out.println(d10.compareTo(d11)); // 0
// BigDecimal也是从Number继承的,也是不可变对象。

public class BigDecimal extends Number implements Comparable<BigDecimal> {
private final BigInteger intVal;
private final int scale;
}

Big类型调用除法时也是如此。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值