1. Java中数字默认是十进制,二进制、八进制以及十六进制的表示如下
2. 二进制、八进制、十六进制和十进制的相互转换
2.1 为了不累赘描述,本文以百度的二进制小数转换为十进制小数为例,如下图
2.2 十进制整数转二进制整数以及十进制小数转换为二进制小数如下
3. 原码、反码和补码
在理解二进制和十进制转换后,对于一个整数,比如 7 ,我们知道二进制表示是 0111,但是一个负数的二进制怎么表示呢,你有想过 -8 怎么用二进制表示吗?在计算机中,存储的都是补码,但是我们前面说的二进制和十进制相互转换都是原码形式。
3.1 对于正数来说,它的原码、反码和补码是一样的。
14,原码:0000 1110,反码:0000 1110,补码:0000 111034,原码:0010 0010,反码:0010 0010,补码:0010 0010
对于负数来说,计算机规定第一位是0表示正数,1表示负数,那么 -14 的原码就是 1000 1110,-34的原码是 1010 0010.那么负数的原码和反码、补码有什么关系呢?
3.2 负数的反码是负数的原码除符号位全部取反;负数补码是负数反码+1
-14,原码:1000 1110,反码:1111 0001,补码:1111 0010-34,原码:1010 0010,反码:1101 1101,补码:1101 1110
有没有感觉这样会有点不对劲,0 和 -0 以及边界,这里以8位示例,对于原码来说,1111 1111表示负数,正数最大只能0111 1111,此时是+127;负数最小是1111 1111,此时是-127。我们学过一个字节有符号正数它的表示范围是-128~127,那么-128怎么表示?
3.3 感觉不对劲的 -0 和 -128 怎么表示
0,原码:0000 0000,反码:0000 0000,补码:0000 0000-0,原码:1000 0000,反码:1111 1111,补码:0000 0000-128,原码:无 反码:无 补码:1000 0000
因此,计算机通过存储补码,一个字节可以存储-128~127的范围,没有 0 和 -0 的区别,存储的都是0000 0000. 同时因为没有数的补码是 1000 0000,那么就直接将 1000 0000表示为 -128,以下通过Java的二进制表示及输出来说明。
注意:以上8位二进制表示前需要加上(byte)类型,如果不加的话,默认是int类型,那么程序在存储时会自动在二进制前面补上24个0,那么以下所有的数字都变为正数。只有加上byte强制转换,那么程序才会在存储时以真实的8位二进制存储,
System.out.println((byte)0b00000000);System.out.println();System.out.println((byte)0b00000001);System.out.println();System.out.println((byte)0b00000010);System.out.println();System.out.println((byte)0b01111110);System.out.println();System.out.println((byte)0b01111111);System.out.println();System.out.println((byte)0b10000000);System.out.println();System.out.println((byte)0b10000001);System.out.println();System.out.println((byte)0b10000010);System.out.println();System.out.println((byte)0b11111110);System.out.println();System.out.println((byte)0b11111111);