Java随机数以及double和float的区别

徐师兄去年毕业到现在也有1年的crud经验了,金九银十准备好好打基础。直接上代码,关于一个中奖概率性问题

DecimalFormat df = new DecimalFormat("#0.0");
int randomInt = RandomUtils.nextInt(0, 100);
System.out.println(randomInt);
if (randomInt>10){
    
    
    System.out.println("概率为90%");
    // 产生0.1-1之间随机数
    System.out.println(df.format(RandomUtils.nextDouble(0.1, 1.0)));
}
if (randomInt<10){
    
    
    System.out.println("概率为10%");
    // 产生1-10之间随机数
    System.out.println(df.format(RandomUtils.nextDouble(1.0, 10.0)));
}
if (randomInt==10){
    
    
    System.out.println("概率是1%");
    // 产生10-100之间随机数
    System.out.println(df.format(RandomUtils.nextDouble(10.0, 100.0)));
}

看着眼熟 是不是像自己中红包时候的概率(苦笑) 其中RandomUtis的maven依赖

		<dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.7</version>
        </dependency>

思考:如何随机从指定的几个小数中取出呢?
业务情景:产品经理要求用户打开对应的活动会获得随机红包,红包大小固定(0.3、0.4、0.5、0.6、0.7、0.8)

//随机生成0.3、0.4、0.5、0.6、0.7、0.8红包金额
String[] amountArr = new String[]{
    
    "0.3", "0.4", "0.5", "0.6", "0.7", "0.8"};
//随机生成整数的数组下标0~5
int index = (int)(Math.random()*6);
String amount = amountArr[index];
//调用红包接口 todo something...
//TODO 限制每个用户只能领一次

好了 这不是本章的重点 主角是double和float两种浮点数类型的区别!


float: 单精度浮点数 占4bytes 有效数字8位 最后一位会四舍五入 声明必须显示0.3f
double: 双精度浮点数 占8bytes 有效数字17位 java中小数都默认是double类型

double myRandomDouble = Math.random();
float myFloat = 3.1415926566f;
double myDouble = 0.69696969699696969;
System.out.println(myRandomDouble);
System.out.println(myFloat + "\n" + myDouble);
System.out.println((double)myFloat);
// print result
0.7739986779428748
3.1415927
0.6969696969969696
3.1415927410125732// 思考为什么末尾会比float类型的3.1415927多这些东西?

通过以上的简单的demo 我们能认识float和double浮点数类型的区别 但是这理解还不够深!(不够长)

思考:为什么在计算机内存小数的存储会存在精度损失呢? double和float为什么叫浮点数 不直接叫小数?

首先我们通过一个老生常谈的面试题说起

System.out.println(0.1f*3==0.3f);
System.out.println(0.1f*3==0.3);
System.out.println(0.1*3==0.3);
// print result
true
false
false

对于计算机而言 它只能识别二进制 所以小数在内存当中是用二进制存储 但是大部分小数都无法毫无精度损失的用二进制存储,只能用最接近二进制来表示;但是如果这个小数不进行任何的计算就会原本的显示出来:double d = 0.69; System.out.print(d);这样就会完整的打印出来;但是如进行了类型转换或者计算就会发生精度损失或在末尾添加一些小数:例如上面的那个demo。


知识点补充:科学计数法形式存储这些小数
例如double d = 69.69; 实际存储的6.969E1,小数点发生“浮动”

那既然double和float处理起来这么麻烦 在《effective java》书中描述:
float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用java.math.BigDecimal。使用BigDecimal并且一定要用String来够造。
此篇不过多的介绍BigDecimal的使用方法,参考点击对应工具类
Java基础补充进制的前缀

// 除了十进制不用前缀,其他都数字0开头
// 二进制数字0和b(大小写都行)
// 八进制数字0开头
// 十六进制数字0和x(大小写都行)
int[] intArr = {
    
    0B101, 017, 123, 0x1a};
Arrays.stream(intArr).forEach(System.out::println);
// print result
5
15
123
26

猜你喜欢

转载自blog.csdn.net/blackxc/article/details/107121239