Java 中的 二进制

Java 中的二进制

二进制是 计算机技术中广泛采用的一种数制。二进制数据是用 0 和 1 两个数码来表示的数。

它的基数为 2,进位规则是 “逢二进一”,借位规则是 “借一当二”


1. 正整数的二进制表示法

十进制二进制十进制二进制十进制二进制十进制二进制
00311611091001
1141007111101010
210510181000111011

1.1 十进制转换成二进制

示例:将 46 转换为二进制

从下往上 46 转换为 二进制: 101110

46 / 2 = 23;// 余 0
23 / 2 = 11;// 余 1
11 / 2 = 5; // 余 1
5 / 2 = 2;  // 余 1
2 / 2 = 1;  // 余 0
1 / 2 = 0;  // 余 1

1.2 二进制转换成十进制

示例: 将 10110 转化为 十进制数

1  0  1  1  1  0
5  4  3  2  1  0 // 每个位上的值代表 2 的 n 次方
32 16 8  4  2  1 // 每个位上的 1 代表的十进制的大小
32+0 +8+ 4+ 2+ 0 = 46    

2. 负整数的二进制表示法

内存中一个字节占 8 位,第一位表示符号位,0 表示正数,1 表示负数

符号位( 0 表示正数,1表示负数)数字位数字位数字位数字位数字位数字位数字位
00101110

2.1 十进制转换为二进制

示例: 将 -46 转换为二进制数

  1. 将 46 转换为二进制数 --> 00101110

  2. 将这个二进制数按位去反 --> 11010001

  3. 最后对二进制数 +1 --> 11010010


2.2 二进制转换为十进制

​ 将 8 位的二进制数字 11010010 转换成十进制

  1. 根据符号位判断 正负
  2. 正数直接按照上面的方法处理
  3. 负数
    1. 先 -1 --> 11010001
    2. 取反 --> 00101110
    3. 再按照正数的方式转换为十进制 46
    4. 加上符号得到最终结果: -46

3. 其他进制

十进制二进制八进制十六进制
0000
1111
21022
31133
410044
510155
611066
711177
81000108
91001119
10101012A
11101113B
12110014C
13110115D
14111016E
16100002010
17100012111
18100102212
19100112313
20101002414

3.1 二进制转换成八进制

  • 将二进制转换为 八进制, 2 的 3 次方等于 8,所以可以将二进制数的每 3 位转换位 8 进制数的 1 位。反之亦然。
  • 如下图 01010111 转换为 八进制为 127


3.2 二进制转换成十六进制

  • 将二进制转换成为 十六进制,由于 2 的 4 次方等于 16,所以可以将二进制的每 4 位 转换成 16 进制数的 1 位。反之亦然。

  • 下图 将 01010111 转换成为 十六进制为 57


4. Java 中的多种进制

4.1 多种进制的表示

  • 十进制

    int a = 10;
    
  • 二进制

    Java 中 0b 或者 0B 开头表示 二进制数

    int b = 0b0010;
    int c = 0B0010;
    
  • 八进制

    Java 中使用 0 开头表示八进制数

    int d = 010;
    
  • 十六进制

    Java 中使用 0x 或 0X 开头表示 十六进制数

    int e = 0x4A;
    int f = 0X4A;
    

4.2 多种进制的转换

  • 整数类型十进制数 转换为二进制字符串

    String binaryNumber = Integer.toBinaryString(100);
    
  • 整数类型十进制数 转换为八进制字符串

    String octalNumber = Integer.toOctalString(100);
    
  • 整数类型十进制数 转换为十六进制字符串

    String hexadecimalNumber = Integer.toHexString(100);
    
  • 将字符串按照指定的进制进行解析

    1. 使用 Integer.valueOf() 方法解析字符串,默认按照 十进制解析,也可以自定义解析方式。
    2. 如果数据不符合解析的进制,会发生 NumberFormatException
    String val = "31";
    Integer.valueOf(val,8);// 按照 8 进制进行解析:25
    Integer.valueOf(val,16);// 按照 16 进制进行解析:49
    

4.3 二进制和 Java 中的数据类型

  • byte

    • Java 中 byte 占 8 位,8 位的二进制数最大为 01111111 --> 转换为十进制 127( 2 7 − 1 2^7 - 1 271

    • 8 位可表示的最小二进制数位 10000000 --> 转换为十进制 -128 ( 2 7 2^7 27

    • byte 的取值范围: -128 ~ 127

      Byte.MIN_VALUE
      Byte.MAX_VALUE
      
  • short

    • 在 Java 中 short 占 16 位

    • short 的取值范围: ( 2 16 − 1 ) (2^{16} - 1) (2161) ~ 2 16 2^{16} 216

      Short.MIN_VALUE
      Short.MAX_VALUE
      
  • int

    • 占 32 位

    • 取值范围: ( 2 32 − 1 ) (2^{32}-1) (2321) ~ − 2 32 -2^{32} 232

      Integer.MIN_VALUE
      Integer.MAX_VALUE
      
  • long

    • 占 64 位

    • 取值范围: ( 2 64 − 1 ) (2^{64} - 1) (2641) ~ 2 64 2^{64} 264

      Long.MIN_VALUE
      Long.MAX_VALUE
      
  • char

    char 类型占 64 位,但是 char 类型没有 符号位(也称 无符号),取值范围 在 0 ~ ( 2 16 − 1 ) (2^{16} - 1) (2161) 之间。


4.4 二进制的浮点数

  • 现代计算机一般以 IEEE 754 标准存储浮点数

    对于 float 类型: 占 32 位,数符分配是 1 位,阶码分配是 8 位,尾数分配是 23 位。

    数符阶码尾数总尾数偏移值
    短实数182332127
    长实数11152641023
    临时实数115648016383
  • 示例: 178.125 转换为 二进制

    • 先把整数部分和小数部分分别转换为 二进制

      • 整数部分:10110010
      • 小数部分:001
      • 合起来:10110010.001
      • 转换为二进制浮点数,即把小数点位移到整数位只有 1,即为: 1.01100100001 ∗ 2 111 1.01100100001 * 2^{111} 1.011001000012111 ( 111是 二进制,左移了 7 位,转换为二进制 就是 111)
    • 把浮点数转换二进制后,对应 3 部分的值

      • 数符:正数,所以是 0
      • 阶码:阶码的计算公式( 阶码 ( 111 )+偏移量( 01111111 ) ) ( 111 + 01111111 = 10000110 ) (111 + 01111111 = 10000110) (111+01111111=10000110)
      • 尾数:小数点后面的数( 011001001 )
    • 最终展示:


4.5 Java 浮点数

  • Java 中浮点数 float 和 int 内存中都占用 32 位,但是 float 的范围要比 int 更大(原因参照上面二进制的浮点数,由于阶码的存在,同样的位数,浮点数可以表示更大的范围),但是也导致 当数值太大以后,尾数位不够大,导致 float 的精度将会下降,所以 虽然 float 类型的范围比 int 大,但是 int 转换为 float 时,可能会出现 精度丢失的情况。

    1.23456792E8 ( 1.23456792 ∗ 1 0 8 1.23456792 * 10^8 1.23456792108 )

    int n = 123456789;
    float f = n;
    System.out.println(n);// 123456789
    System.out.println(f);// 1.23456792E8 
    

5. 位运算符

5.1 非( ~ )

非运算:按位取反。

( int 为 32 位,前面的 0 省略 )

x11111010
500000101
int x = ~5; // -6

5.2 与( & )

与运算:只有当两个操作数都为 1 的时候才取 1,否则就取 0。

( int 为 32 位,前面的 0 省略 )

x00000100
600000110
500000101
int x = 5 & 6; // 4

5.3 或( | )

或运算:只要有一个操作数为 1 结果就为 1。

( int 为 32 位,前面的 0 省略 )

x00000111
500000101
600000110
int x = 5 | 6;// 7

5.4 异或( ^ )

异或运算:当两个操作数不同时,结果为 1;两个操作数相同时,结果为 0。

( int 为 32 位,前面的 0 省略 )

x00000011
500000101
600000110
int x = 5 ^ 6; // 3

5.5 右移( >> )

  • > > >> >> 移位运算符:将所有操作数向 右 位移 n 位,前面空出的用 符号位 补足( 正数补 0,负数 补 1 ),移出的舍去。

  • 正数右移相当于十进制除法运算除以 2 n 2^n 2n

( int 为 32 位,前面的 0 省略 )

500000101
x00000010
y00000001
int x = 5 >> 1// 2
int y = 5 >> 2; // 1    

5.6 左移( << )

  • < < << << 移位运算符:将所有操作数向左 位移 n 位,后面补足 0。

  • 正数左移相当于十进制乘法运算操作数乘以 2 n 2^n 2n

( int 为 32 位,前面的 0 省略 )

500000101
x00001010
y00010100
int x = 5 << 1; // 10
int y = 5 << 2; // 20

5.7 无符号右移( >>> )

> > > >>> >>> 无符号右移:将所有操作数向 右 位移 n 位,前面空出的用 0 补足,对于正数 与 > > >> >> 运算相同,对于负数 > > > >>> >>> 运算后将变为正数。


5.8 问题

  • 有 10 瓶药,其中有 若干瓶 坏药,已知 好药每颗重 1 克,坏药每颗重 0.9 克,有一个秤,只能秤一次,找到所有的坏药。

    药瓶编号12345678910
    取出药数 2 1 2^1 21 2 2 2^2 22 2 3 2^3 23 2 4 2^4 24 2 5 2^5 25 2 6 2^6 26 2 7 2^7 27 2 8 2^8 28 2 9 2^9 29 2 10 2^{10} 210
    实际重量1101101101
    最大重量1111111111

参考博客:浮点数的二进制表示(IEEE 754标准)


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值