进制
进制,也就是进位制,是人为规定的一种进位方法,逢临界值则进一,例如:十进制就是逢十进一,八进制就是逢八进一,二进制就是逢二进一。
以整型115为例:十六进制(73),十进制(115),八进制(163),二进制(111 0011)。
二进制
二进制,它由两个基本数字0,1组成,它的规则是逢二进一。
以十进制整数115为例,它的转化方式:
- 将115/2=57=========余1;
- 将57/2=28==========余1;
- 将28/2=14==========余0;
- 将14/2=7===========余0;
- 将7/2=3============余1;
- 将3/2=1============余1;
- 将1/2=0============余1;
- 商为0结束,把余数从下往上连接,最后的值为:111 0011。
以十进制小数0.625为例,它的转化方式:
- 将0.625*2=1.25======取出整数部分1
- 将0.25*2=0.5========取出整数部分0
- 将0.5*2=1 ==========取出整数部分1
- 小数部分为0结束(或者达到所要求的精度为止),把取出整数部分从上往下连接,得101,最后的值为:0.101。
八进制
八进制,它由八个基本数字组成0,1,2,3,4,5,6,7,它的规则是逢八进一。
以十进制115为例,它的转化方式:
- 将115/8=14==========余3;
- 将14/8=1============余6;
- 将1/8=0=============余1;
- 商为0结束,把余数从下往上连接,最后的值为:163。
以十进制小数0.625为例,它的转化方式:
- 将0.625*8=5======取出整数部分5
- 小数部分为0结束(或者达到所要求的精度为止),把取出整数部分从上往下连接,得5,最后的值为:0.5。
十进制
十进制,它由十个基本数字组成0,1,2,3,4,5,6,7,8,9,它的规则是逢十进一。转化方式省略。
十六进制
十六进制,它由16个基本数字和字母组成0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,它的规则是逢十六进一,并且它从9开始由字母a代替10,字母b代替11,依此类推。转化方式省略。
当然进制也不仅仅局限上述几种,只不过用的最多上述几种。
java关于十进制转为其他进制的方法,以Integer类示例如下:
int i = 115;
// 二进制
System.out.println(Integer.toBinaryString(i)); // 1110011
// 十六进制
System.out.println(Integer.toHexString(i)); // 73
// 八进制
System.out.println(Integer.toOctalString(i)); // 163
/**
* String toString(int i, int radix);
* i: 需要转换的数字,十进制
* radix: 基数, 范围:Character.MIN_RADIX(2) - Character.MAX_RADIX(36), 若在这范围之外,则指定为10
*/
System.out.println(Integer.toString(i, 8)); // 163
当然,还有Long、Character类。Long类的处理方式和Ineger类相似,就不举例了,看Character类的转换示例如下:
String arg = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ+-*/=你好";
StringBuffer sb = new StringBuffer(arg.length());
for (byte c : arg.getBytes()) {
/**
* char forDigit(int i, int radix)
* i: 需要转换的数字,十进制
* radix: 基数, 范围:Character.MIN_RADIX(2) - Character.MAX_RADIX(36), 若在这范围之外,则返回'\0'
*/
sb.append(Character.forDigit(c & 0xf, 16));
}
System.out.println(0163); //115, 八进制
System.out.println(0xf); // 15, 十六进制
System.out.println(0Xfff); // 4095, 十六进制
System.out.println(sb.toString()); // 123456789abcdef0123456789a123456789abcdef0123456789abdafd4d055d
如你所见,java的数字也可以使用0163和0xf(0Xf、0xF、0XF),它们分别代表了八进制和十六进制。之所以用"c & 0xf“,因为这里需要结果把转换成16进制,并且"c & 0xf“得到结果只会在0~15之间,这刚好符合16进制的范围。(位运算符"&",该符号表示逻辑与)
关于进制,还需要了解下原码、反码和补码。一个数在机器上是以二进制的方式存储的,由于数是有正负之分的,因此规定二进制的最高位为符号位,其他位为真正的数值,若3的二进制为0000 0011,而-3的二进制为1000 0011。
原码
原码就是符号位加上真正数值的绝对值,即第一位为符号位,其他位为真正的数值。例如:1的原码:0000 0001,而-1的原码:1000 0001。
反码
正数的反码是其本身,而负数的反码是符号位不变,其他位按位非(取反)。例如:1的反码:0000 0001,而-1的反码:1111 1110。
补码
正数的补码是其本身,而负数的反码是符号位不变,其他位按位非(取反),最后+1。(也可以理解为反码+1)例如:1的补码:0000 0001,而-1的补码:1111 1111。
为何会出现反码和补码呢?由于机器只有加法,没有其他运算符,而若是只使用原码,算法出错,例如:1-1 =》0000 0001 + 1000 0001 = 1000 0010 = -2,而实际的结果不一致。这时才出现了反码和补码。