深入二进制

  1. 什么是二进制:逢2进1的计数规则。计算机中的变量/常量都是按照2进制来计算的
    • 2进制:
      • 规则:逢2进1
      • 数字:0 1
      • 基数:2
      • 权:128 64 32 16 8 4 2 1
    • 如何将2进制转换为10进制:
      • 将二进制每个1位置的权相加即可---------------正数
			权:    32  16  8  4  2  1
           二进制: 1   0   1  1  0  1
           十进制: 32+8+4+1=45
			int n = 45; //编译时会被编译为:101101
           System.out.println(Integer.toBinaryString(n)); //以2进制输出
           System.out.println(n); //以10进制输出
       n++; //将101101增1----101110
       System.out.println(Integer.toBinaryString(n)); //以2进制输出
       System.out.println(n); //以10进制输出
  1. 十六进制:逢16进1的计数规则
    • 16进制:

      • 规则:逢16进1
      • 数字:0 1 2 3 4 5 6 7 8 9 a b c d e f
      • 基数:16
      • 权:4096 256 16 1
    • 用途:因为2进制书写太麻烦,所以常常用16进制来缩写2进制

    • 如何缩写:将2进制从低位开始,每4位2进制缩为1位16进制

      权:           8  4  2  1
      2进制:  0001 1011 1010 1010 0101
      16进制:  1    b    a    a    5-----------1baa5
      
      权:           8  4  2  1
      2进制:  0010 1111 1101 0100 0111 1011
      16进制:   2   f    d    4    7    b------2fd47b
          
      权:           8  4  2  1
      2进制:  0010 1001 0101 1010 1011 1001
      16进制:  2    9    5    a    b    9
      
      //演示16进制
      int n = 0x2fd47b; //0x表示16进制
      int m = 0b0010_1111_1101_0100_0111_1011; //0b表示2进制
      System.out.println(Integer.toBinaryString(n)); //按2进制输出
      System.out.println(Integer.toBinaryString(m));
      System.out.println(Integer.toHexString(n)); //按16进制输出
      System.out.println(Integer.toHexString(m));
      System.out.println(n); //按10进制输出
      System.out.println(m);
      
      //演示8进制
      int a = 067; //以0开头的表示8进制
      System.out.println(a); //55(6个8加7个1)
      /*
      小面试题:-----8进制平时不用
      int a = 068; 正确吗?
      答:编译错误,因为0开头的表示8进制,最大的数为7
      */
      
  2. 补码:
    • 计算机处理有符号数(正负数)的一种编码方式
    • 以4位2进制为例讲解补码的编码规则:
      • 计算的时候如果超出4位则高位自动溢出舍弃,保持4位不变
      • 将4位2进制数分一半作为负数使用
      • 最高位称为符号位,高位为1是负数,高位为0是正数
    • 规律数:
      • 0111为4位补码的最大值,规律是1个0和3个1,可以推导出
        • 32位补码的最大值:1个0和31个1------(01111111111111111111111111111111)
      • 1000为4位补码的最小值,规律是1个1和3个0,可以推导出
        • 32位补码的最小值:1个1和31个0------(10000000000000000000000000000000)
      • 1111为4位补码的-1,规律是4个1,可以推导出
        • 32位补码的-1:32个1----------------------(11111111111111111111111111111111)
		 int max = Integer.MAX_VALUE; //int的最大值
         int min = Integer.MIN_VALUE; //int的最小值
         System.out.println(Integer.toBinaryString(max));  //01111111...
         System.out.println(Integer.toBinaryString(min));  //10000000...
         System.out.println(Integer.toBinaryString(-1));   //11111111...
  • 深入理解负值:
    • 记住32位二进制数的-1的编码:32个1
    • 负值:用-1减去0位置对应的权---------------负数
		   1)11111111111111111111111111111111 = -1
           2)11111111111111111111111111111101 = -1-2 = -3
           3)11111111111111111111111111111010 = -1-1-4 = -6
           4)11111111111111111111111111110111 = -1-8 = -9
           5)11111111111111111111111111110101 = -1-2-8 = -11
           6)11111111111111111111111111010011 = -1-4-8-32 = -45
           //负值的输出
           int n = -45;
           System.out.println(Integer.toBinaryString(n)); //以2进制输出
           int m = -11;
           System.out.println(Integer.toBinaryString(m)); //以2进制输出
  • 互补对称现象:-n=~n+1--------取反+1

     -7    = 11111111 11111111 11111111 11111001 = -1-2-4=-7
    ~-7   = 00000000 00000000 00000000 00000110 = 2+4=6
    ~-7+1 = 00000000 00000000 00000000 00000111 = 1+2+4=7
    
    5     = 00000000 00000000 00000000 00000101 = 1+4=5
    ~5    = 11111111 11111111 11111111 11111010 = -1-1-4=-6
    ~5+1  = 11111111 11111111 11111111 11111011 = -1-4=-5
        
    12    = 00000000 00000000 00000000 00001100 = 4+8=12
    ~12   = 11111111 11111111 11111111 11110011 = -1-4-8=-13
    ~12+1 = 11111111 11111111 11111111 11110100 = -1-1-2-8=-12
    //互补对称现象: -n=~n+1
    int n = -7;
    int m = ~n+1;
    System.out.println(m); //7
    int i = 12;
    int j = ~i+1;
    System.out.println(j); //-12
    int a = 2147483647; //int的最大值
    a = a+1;
    System.out.println(a); //-2147483648(int的最小值)
    
    int b = -2147483648; //int的最小值
    b = b-1;
    System.out.println(b); //2147483647
    
  1. 位运算:
    • 取反:~
      • 运算规则:0变1,1变0
    • 与运算:&
      • 运算规则:逻辑乘法,见0则0

        0 & 0 ---------> 0
        0 & 1 ---------> 0
        1 & 0 ---------> 0
        1 & 1 ---------> 1
        
        n =       00010111 01110101 01111010 11110110----0x17757af6
        m =       00000000 00000000 00000000 11111111----0xff
        k = n&m = 00000000 00000000 00000000 11110110----0xf6 
        
        int n = 0x17757af6;
        int m = 0xff; //8位掩码
        int k = n&m;
        System.out.println(Integer.toBinaryString(n));
        System.out.println(Integer.toBinaryString(m));
        System.out.println(Integer.toBinaryString(k));
        如上运算的意义:k中储的是n的最后8位,这种运算叫做掩码运算
                     一般从低位开始1的个数称为掩码的位数
        
    • 或运算:|
      • 运算规则:逻辑加法,见1则1

        0 | 0 ----------> 0
        0 | 1 ----------> 1
        1 | 0 ----------> 1
        1 | 1 ----------> 1
        
        n       = 00000000 00000000 00000000 11011110  0xde
        m       = 00000000 00000000 10011101 00000000  0x9d00
        k = n|m = 00000000 00000000 10011101 11011110  0x9dde
        
        int n = 0xde;
        int m = 0x9d00;
        int k = n|m; //将n和m错位合并
        System.out.println(Integer.toBinaryString(n));
        System.out.println(Integer.toBinaryString(m));
        System.out.println(Integer.toBinaryString(k));
        
    • 右移位运算:>>>
      • 运算规则:将2进制数整体向右移动,低位自动溢出舍弃,高位补0

        n =        01101011 00111111 01011110 00111010----0x6b3f5e3a
        m = n>>>1  00110101 10011111 10101111 00011101
        k = n>>>2  00011010 11001111 11010111 10001110
        g = n>>>8  00000000 01101011 00111111 01011110
        
        int n = 0x6b3f5e3a;
        int m = n>>>1;
        int k = n>>>2;
        int g = n>>>8;
        System.out.println(Integer.toBinaryString(n));
        System.out.println(Integer.toBinaryString(m));
        System.out.println(Integer.toBinaryString(k));
        System.out.println(Integer.toBinaryString(g));
        
    • 左移位运算:<<
      • 运算规则:将2进制数整体向左移动,高位自动溢出舍弃,低位补0

        n =        01101110 10111100 00111011 00111011-------0x6ebc3b3b
        m = n<<1   11011101 01111000 01110110 01110110
        k = n<<2   10111010 11110000 11101100 11101100
        g = n<<8   10111100 00111011 00111011 00000000
        
        int n = 0x6ebc3b3b;
        int m = n<<1;
        int k = n<<2;
        int g = n<<8;
        System.out.println(Integer.toBinaryString(n));
        System.out.println(Integer.toBinaryString(m));
        System.out.println(Integer.toBinaryString(k));
        System.out.println(Integer.toBinaryString(g));
        
    • 移位运算的数学意义:
		 int n = 5;
         int m = n<<1;
         int k = n<<2;
         int g = n<<3;
         System.out.println(m); //10----相当于5*2
         System.out.println(k); //20----相当于5*4
         System.out.println(g); //40----相当于5*8
         /*
           权:  64  32  16  8  4  2  1
           n:               0  1  0  1 = 5
           m:           0   1  0  1    = 10
           k:       0   1   0  1       = 20
           g:   0   1   0   1          = 40
         */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中的二进制序列化是将对象转换为二进制数据的过程,以便在存储或传输时能够保留对象的状态。深入理解二进制序列化可以帮助我们更好地掌握其工作原理和灵活运用。 在C#中,可以使用`BinaryFormatter`类来进行二进制序列化。首先,需要将要序列化的对象标记为可序列化,可以通过在类定义前加上`[Serializable]`特性来实现。然后,可以使用`BinaryFormatter`的`Serialize`方法将对象序列化为二进制数据。 以下是一个简单的示例: ```csharp [Serializable] class MyClass { public int MyProperty { get; set; } public string MyField; } class Program { static void Main() { MyClass obj = new MyClass(); obj.MyProperty = 42; obj.MyField = "Hello, world!"; BinaryFormatter formatter = new BinaryFormatter(); using (FileStream stream = File.Create("data.bin")) { formatter.Serialize(stream, obj); } } } ``` 上述代码将一个`MyClass`对象序列化为名为"data.bin"的二进制文件。 要理解二进制序列化的工作原理,可以了解以下几点: 1. 序列化过程会将对象的字段和属性转换为字节流,并将其写入流中。反序列化时则会将字节流读取并转换回对象的字段和属性。 2. `BinaryFormatter`会自动处理对象图中的引用关系,确保在序列化和反序列化过程中能够正确还原对象之间的引用关系。 3. 对于自定义类型,需要确保所有要序列化的字段和属性都是可序列化的。非可序列化的字段和属性可以通过标记为`[NonSerialized]`特性来排除。 4. 序列化过程中可能会遇到无法序列化的类型或对象,可以通过实现`ISerializable`接口来自定义序列化和反序列化过程。 5. 序列化是一种用于持久化对象状态或进行远程通信的常见技术,但需要注意安全性和性能等方面的考虑。 希望这些信息能够帮助你更深入地理解C#二进制序列化的概念和使用方法。如果有任何进一步的问题,请随时提问!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值