Java控制小数位,获得随机数
怎么说呢,因为测试加速器所以创建了一个模拟的输出随机数,因为Android的随机数有两种写法,结果就跟输出随机杠上了,强迫症一犯,就干脆把各种随机数的几种写法重新总结了下,结果之后又因为Math对象的random方法跟小数位杠上了,总结了一下获得随机数的方法,和小数位的处理方法。
因为很多方法是API上面的,如果有兴趣可以自己去API查看。我这里只是稍微说一下我用的情况。
第一次写博客,没啥经验,之前因为懒,所以就没有发过。。。
- Random对象获取随机数
- Math对象获取随机数
处理小数位
- 直接格式化输出
- 类型转换(n.0格式)
- 类型转换(n.m格式)
- 数字格式化对象(NumberFormat)
- 十进制数字格式化对象(DecimalFormat)
- 16位以上数据为了保证精度(BigDecimal)
Random对象获取随机数
需要知道的是,Random对象获得的随机数都是伪随机数,是根据一个真随机数生成的。
返回值 | 方法 |
---|---|
protected int | next(int bits) |
boolean | nextBoolean() |
void | nextBytes(byte[] bytes) |
double | nextDouble() |
float | nextFloat() |
int | nextInt() |
int | nextInt(int n) |
long | nextLong() |
double | nextGaussian() |
void | setSeed(long seed) |
详解:
1.next(int bits)
完全不用的一个方法,返回一个int类型的随机数。但是因为修饰类型为protected,所以使用该方法的类必须继承Random(class 类名 extends Random)
2.nextBoolean()
随机给一个true或者false;
3.nextBytes(byte[] bytes)
唯一的获得随机数但是没有返回值的方法,因为返回值会被存进作为参数的bytes数组中。
代码:
import java.util.Random;
public class TestRandom {
public static void main(String[] args) {
// 获得随机数对象
Random random = new Random();
// 新建byte数组,同时设定生成的byte数的个数
byte[] bytes = new byte[10];
// 存入随机数组
random.nextBytes(bytes);
// 遍历输出
for (byte b : bytes) {
System.out.println("byte:" + b);
}
}
}
输出:
byte:12
byte:96
byte:109
byte:-124
byte:-18
byte:39
byte:-14
byte:44
byte:36
byte:-22
4.nextDouble()
随机返回一个0.0d(包括)到 1.0d(不包括)范围内的double值。
5.nextFloat()
随机返回一个0.0f(包括)到 1.0f(包括)范围内的float值。
6.nextInt()
在int对象取值范围内随机生成一个int类型随机数返回。
7.nextInt(int n)
返回一个在 0(包括)和指定值(不包括)之间均匀分布的 int 值
8.nextLong()
在long对象取值范围随机生成一个long类型随机数返回
9.nextGaussian()
高斯分布的doule类型随机数,其平均值是 0.0,标准差是 1.0。相信我,除了少数一些人,基本上用不到。
10.setSeed(long seed)
设置随机数种子,因为Random生成随机数都是基于一个真随机数生成的伪随机数,这个就是他的种子。一般不会用到的,有人想用到话,可以参考这种方法
import java.util.Random;
public class TestRandom {
public static void main(String[] args) {
// 获得随机数对象
Random random = new Random();
// 设置种子
random.setSeed(20);
// 用设置了种子的随机数对象生成100以内的随机数,0~99
int i = random.nextInt(100);
}
}
Math对象获得随机数
Math获得随机数只有一种方式,调用该类的random()方法,随机产生一个大于等于 0.0 且小于 1.0的double类型小数值
代码:
public class TestRandom {
public static void main(String[] args) {
// 获得随机数
double random = Math.random();
// 输出信息
System.out.println("This is a random for double:"+random);
}
}
输出:
This is a random for double:0.14258442581708097
处理小数位
很明显,这里出现了一个状况,那就是double类型的随机数小数位过长,用来输出简直……
好吧 ,丧心病狂,而且因为很多人一般都是自定义一个小数,然后赋值给double或者float类型的变量。所以我就把我用的方法总结了一下。各位看自己情况来使用吧。
直接格式化输出
这个是常用,一般控制台输出都是直接这样输出,因为我是做Android开发的,所以这种输出对我来说并不是最好的,但是方便各位,就写在前面了。
代码:
public class TestRandom {
// 这种格式化会自动四舍五入,并不是单纯的掐掉尾巴
public static void main(String[] args) {
// 定义两个变量用以测试
double d1 = 0.125;
double d2 = 0.124;
// 直接格式化输出,这里的printf是正确的,不是我打错了。
System.out.printf("%.2f", d1);
// 因为不使用println就没有自动换行的效果,所以就加上换行符
System.out.print("\n");
System.out.printf("%.2f", d2);
}
}
输出:
0.13
0.12
类型转换(n.0格式)
这种是比较适合初学者来用的,简单易懂。但是处理效果不佳。因为虽然保留着小数的样子,但是.0固定结尾其实对我们来说还有什么意义呢。但是你不得不承认,某些情况下,会有这种要求的。
但是有个问题就是,这样转换,相当于直接把小数点后面的抹掉,哪怕是n.99输出结果也是n.0,而不是n+1
代码:
public class TestRandom {
public static void main(String[] args) {
// 定义double变量
double d = 5.925;
// 强制转换成int类型。
int i=(int) d;
// 转回double类型。
double d2=i;
// 输出查看
System.out.println(d2);
}
}
输出:
5.0
类型转换(n.m格式)
这个方法比较作弊,也是我一直在用的,毕竟在Android平台,new对象是一种比较占用内存的方式,为了节省内存,我一般会这样处理。
但是作弊的方法,还是有缺点的,因为是上一种方法的变种,所以这个方法依然不会四舍五入,而是抹除所多余的小数位
代码:
public class TestRandom {
public static void main(String[] args) {
// 定义double变量
double d = 5.925;
// 根据小数位,有几位,乘以10的几次方,强制转换成int类型。
int i = (int) (d * 100);
// 转回double类型,然后将乘上的数重新除去。
double d2 = (double)i / 100;
// 输出查看
System.out.println(d2);
}
}
输出:
5.92
数字格式化对象(NumberFormat)
数字格式化,通过方法格式化,可以对多种状态使用,但是本身使用不好理解。
代码:
import java.text.NumberFormat;
public class TestRandom {
public static void main(String[] args) {
// 定义double变量
double d = 5.925555555;
// 抽象类方法,构造方法因为被protected了,所以只能通过静态方法获得。
NumberFormat Nformat=NumberFormat.getInstance();
// 设置小数位数。
Nformat.setMaximumFractionDigits(2);
// 执行格式化转换。
String string = Nformat.format(d);
// 输出查看
System.out.println(string);
}
}
输出:
5.93
十进制数字格式化对象(DecimalFormat)
十进制的格式化器
代码:
import java.text.DecimalFormat;
public class TestRandom {
public static void main(String[] args) {
// 定义double变量
double d = 15.925555555;
// 新建格式化器,设置格式
DecimalFormat Dformat=new DecimalFormat("0.00");
// 根据格式化器格式化数据
String string=Dformat.format(d);
// 输出信息确认
System.out.println(string);
}
}
输出:
15.93
16位以上数据为了保证精度(BigDecimal)
这个放在最后不是因为不重要,只是用来格式化的话,有些屈才了,他是用来对超过16位有效位的数进行精确的运算的。里面功能很丰富,属于java.math包
处理结果还是double类型,如果需要,可以保留计算。
代码:
import java.math.BigDecimal;
public class TestRandom {
public static void main(String[] args) {
// 定义double变量
double d = 15.925555555;
// 新建格式化器,设置格式
BigDecimal decimal=new BigDecimal(d);
// 将数据四舍五入为两位小说的double值
double d2=decimal.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
// 输出信息确认
System.out.println(d2);
}
}
输出:
15.93
顺便附注一个话题,将字符串转换浮点数,精度天生就会出现偏差的,因为浮点数存储的并不是真正的我们看到的数,而是经过偏移转换的近似值。所以才会有上面BigDecimal对象,如果需要计算浮点数,最好使用BigDecimal对象。