继续java基础的复习。。。今天主要复习浮点数在计算机中的存储过程,以及equals方法和==判断两个对象相等时有什么区别。
Q:浮点数在计算机中是如何进行存储的?说一下存储过程
A:在计算机中所有的数据都是由二进制0,1表示的,在java中整数是用二进制补码表示,而在java中浮点数在计算机中的存储是按IEEE754浮点数规格化来规范的,在IEEE754规范中并没有将32位单精度浮点数命名为float,以及将64位双精度浮点数命名为double。它只是将浮点数进行了规范。具体规范如下:32位单精度浮点数在计算机中是这样存储的:它用最高的1位即第31位来表示符号位,1表示负数,0表示正数;用接下来的8位表示指数位,即23位到30位,用移码表示。最后用0-22,这23位来表示尾数,用原码表示,格式为1.xxxxx,小数点前为非0的数字,也就是1。移码的实现是在原码基础上再加一个偏移量,32位单精度浮点数的偏移量为+127(具体转换即是在该数的补码表示中将最高符号为取反即为移码)。具体存储过程如下:首先将十进制小数转化为纯二进制小数,然后将二进制小数转化为二进制指数形式(将小数点移至一个数和第二个数之间,且第一个数为1)然后将底数与指数相分离,指数部分按移码表示,底数部位也就是尾数部分按源码表示,并且将尾数部分小数点和小数点之前的1省略(这是IEEE754的一种约定,可以扩大表示的范围,及相比其他浮点数规格化可以多表示一位)然后将各个段按位补齐补0。然后以 数符+指数+尾数 这种顺序连接起来,计算机浮点数就是这种形式存储的。至于64位双精度浮点数,它最高位为数符,接下来11位表示指数,用移码表示,最后52位表示尾数按源码表示,具体存储过程和单精度类似。单精度取值范围大概在[-3.4*10^38, 3.4 * 10^38],双精度浮点数的取值范围在[-2.23*10^308~+2.23*10^308]。
Q:equals和==判断两个对象相等时有什么区别?
A:使用==来判断两个对象是否相等时,是直接比较两个对象的堆内地址,如果相等则说明这两个引用指向的是同一块内存区域。那么可能会问既然比较的是地址那么int类型又是怎样比较的?String类型又是怎么比较的?对于基本数据类型他们是作为常量放在方法区里的常量池里的。在常量池中一个常量只会对应一个地址,不管你创建多少个123这种数据它都只会在内存中存在一个地址,它们的引用都指向同一个地址,所以对于基本数据类型和String数据类型它们是可以直接用==来判断相等的。对于包装类型它们也存在常量池这种概念。比如Integer,它也有常量池范围为-128-+127在这个范围内创建创建对象由于这些值在常量池中存在,在内存中只对应一个地址,当然这里不包括使用new关键字创建的对象。而equals方法呢,可以知道equals方法是所有的父类Object类中的public方法,在Object方法中它的实现实际上就是使用==来判断相等的。但是也正是由于它是Object类的公有方法,所以子类是可以重写它的,因此在不同环境下equals的实现方法也会有差异,比如我们自定义一个Student类,我们认为如果这两个学生对象的学号相同,那么我们就认为他们是同一个学生认为他们两个对象之间equals方法的返回值为true。当然我们也可以将equals方法直接返回true,认为所有对象都是相等的。因此==判断两个对象是否相等,实际判断的是对象的堆内地址,而equals方法在没有重写Object方法中的equals方法之前它实际也就是==。但是在不同环境下的equals方法的实现方式不同它判断相等的依据也会不同。相比较equals更灵活。