之所以学习,就是由于下面的代码引出的:
结果是 0.5999985,而不是 0.6
学到的
一、原码、反码、补码
正数和0(注意:包括0):原码、反码、补码 统统都是一样的
负数
原码:绝对值的原码(当然就是正数的原码,其最前面符号位就是0),然后,把最前面的符号位0变为1
反码:对自己的(负数本身)原码进行捣鼓:最前面的符号位1不变,剩下的各位取反
补码:对自己的(负数本身)原码进行捣鼓:最前面的符号位1不变,剩下的各位取反,然后某位加1
移码:对于同一个整数(无论正负),其移码与其补码数值位完全相同,而符号位正好相反
举例如下:
十进制数 | 原码 | 反码 | 补码 | 移码 |
-127 | 11111111 | 10000000 | 10000001 | 00000001 |
-1 | 10000001 | 11111110 | 11111111 | 01111111 |
-0 | 10000000 | 11111111 | 00000000 | 10000000 |
+0 | 00000000 | 00000000 | 00000000 | 10000000 |
+1 | 00000001 | 00000001 | 00000001 | 10000001 |
+127 | 01111111 | 01111111 | 01111111 | 11111111 |
二、补码的个人理解
补码:补码是针对于mod来说的,要说某个数的补码,必须说,此时mod是多少。
补码的概念定义很重要,在定义中我们可以得知,如果提到补码,则必须说明mod,否则补码没有意义。(至于“按位取反,末尾加1”,则是碰巧的事)
三、定点数:包括 定点小数 和 定点整数
定点小数的表示范围是:2- n ≤ | x | ≤ 1 - 2- n
定点整数的表示范围是:1≤ | x | ≤ 2n - 1
四、Java中数值在内存中是如何表示的
整数:无论正负,在内存中,都是用补码表示的(Java中)
float,double:在内存中,按着IEEE-754来表示的(Java中)
五、浮点数
这个就不说了,记得里面有个隐藏位,而且记得,阶码必须要-127或者-1023
六、和Java API相关的
给定一个整数(无论正还是负,Java中32位表示一个整数),Integer.toBinaryString(),得到此数在内存中的表示形式,也就是,得到此数的补码。一个整数,无论正负,在内存中,都是用补码表示的
给定一个float数(无论正还是负,Java中32位表示一个float,且float是IEEE-754标准),Float.floatToIntBits()按着此float在内存中的0、1结构,得到这个结构所表示的整数
举例如下:
例如:float=34.6f中,事实上,我们看到的34.6f,在内存中值换算成十进制:3.4599998474121094,其二进制是:0100 0010 0000 1010 0110 0110 0110 0110(这个二进制是IEEE-754格式的,1个符号位,8个阶码位,23个数值位,事实上,有个隐藏位,就在阶码位后面,其值为1。当然,这个隐藏位在Float.floatToIntBits()没有任何作用,Float.floatToIntBits()严格按着这里的 bit layout得到一个整数的补码,根据这个整数的补码,可以得到这个整数,或正或负)
对于64位的 long和double,也有同样相似的方法