晨讲知识点

小数计算不精确问题

(1)问题引入:

在这里插入图片描述在这里插入图片描述

0.1*3在计算后不等于0.3,存在问题:小数计算不精确.

(2)问题深入探究

在这里插入图片描述在这里插入图片描述

计算机浮点数计算不精确,本质上是计算机中浮点数保存不精确,十进制浮点数转为二进制浮点数时出现了无限循环,计算机保存不了所有数据,把多余的截去了,导致保存的浮点数不精确,所以得到的计算结果不可能精确.

(3)java中的浮点数为什么能精确打印?在这里插入图片描述

经过寻找找打印函数的实现发现在下面的Double.toString(double d)中调用的方法中经过了一系列计算返回了一个String对象
在这里插入图片描述在这里插入图片描述

这说明了java能精确的打印是因为sun公司的大佬研究了浮点数在计算机中的存储形式和截去规律搞了一波反向计算还原了原来的值(以字符串的形式),我们就到此为止就可以了.

(4)BigDecimal能精确计算的原因

在这里插入图片描述
在这里插入图片描述

因为浮点数在计算机中的保存形式是不精确的,所以通过浮点数进行计算肯定得不到我们想要的值,所以说,计算机浮点数计算不精确的说法不准确,计算机浮点数保存不精确更合理.BigDecimal解决了计算机浮点数计算不精确的说法更不准确了,说BigDecimal解决了计算机浮点数保存不精确更合适.
当我们用传入字符串形式创造BigDecimal对象时,计算机是以字符串形式保存这个浮点数而不是用该数字的二进制形式保存,进行计算的时候BigDecimal会先把该字符串形式的小数转为整数参与运算,然后把结果再转回字符串形式的小数.

我们传入字符串,但是生成对象时用的是以该字符串为蓝本的字符数组
在这里插入图片描述

举例:

计算0.13
字符串”0.1”,先通过toCharArray()转为字符数组[‘0’,’.’,’1’],记录此时的数组长度和小数点位置
计算时把0.1转为整数,就是去掉小数点,变为字符数组‘0’,’1’,并记录1代表扩大了10的1次方,然后通过String.Valueof()把得到的数组变为字符串”01”,再通过Integer.parseInt()转成数字1,1在计算机中能精确保存,1
3=3,把得到的数字用String.valueOf()再转成字符串,再转成字符数组,再通过之前保存的数字1插入小数点和补字符0,得到字符数组[‘0’,’.’,’3’],最后转成字符串”0.3”,就完成了.
原理是这样,BigDecimal中过程会和这有出入,比如计算时3也要完成转BigDecimal等.

mysql的group by问题以及where和having替换问题

在这里插入图片描述

(1)首先探究where和having的替换

i.当条件字段在是查询字段之一时where和having都可以
在这里插入图片描述

Ii.当条件字段是表格字段但不属于查询字段时只能用where
在这里插入图片描述

iii.当满足i同时起了别名,用原名进行条件查询where和having都可以
在这里插入图片描述

iv.当满足i同时起了别名,用别名进行条件查询只能用having
在这里插入图片描述

(2)探究group by

现在需求为查询各组分数最低的同学的所有信息
可以想到的错误答案:
select * from (select * from grou order by score)s group by gro;
超乎想象的正确答案:
select * from (select * from grou order by score limit 10)s group by gro;
在这里插入图片描述

结论:
Group by 分组后每组只保留了一条信息,并且在不做干涉的情况下默认留的是主键值最小的那条信息,干涉方法之一是加limit

可能和版本有关,我自己的mysql就没有这个问题.
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43770110/article/details/120912995
今日推荐