zoukankan      html  css  js  c++  java
  • 位运算 & 网络序字节序

    一、初识位运算

    位运算,见词明意,二进制运算,通常需要将运算数转换为二进制再进行处理,如果是在程序语言中则无需自己进行进制转换,基本的位操作符有如下几种:与(&)、或(|)、异或(^)、取反(~)、左移(<<)、右移(>>),它们的运算规则如下所示:

     

    扩展:进制转换

      此处简单提一下进制转换:bit表示一个二进制位;byte表示一个字节(8bit),表示-128至127之间的整数值;整数234567的内存写照为:00000000 00000011 10010100  01000111(十进制转换为二进制);Java中二进制、八进制、十进制、十六进制间相互转换,方式如下:

      十进制转成二进制:

        Integer.toBinaryString(int i)

      十进制转成八进制:

        Integer.toOctalString(int i)

      十进制转成十六进制:

        Integer.toHexString(int i)

      二进制转十进制:

        Integer.valueOf("0101",2).toString()

      八进制转成十进制:

        Integer.valueOf("876",8).toString()

      十六进制转成十进制:

        Integer.valueOf("FFFF",16).toString()

      上面提到的几种进制转换都是由Java的内置方法进行处理的,正负整数在计算机内部的写照可以参考[负数的二进制表示方法]进行手工转换,我们知道负数在计算机内部是用补码表示的,则针对负整数-3976,从原码、反码、补码角度来看其在计算机内部的写照:

    原码:0000 0000 0000 0000 0000 1111 1000 1000

    反码:1111 1111 1111 1111 1111 0000 0111 0111

    补码:1111 1111 1111 1111 1111 0000 0111 1000

    由上可知,-1的内存写照为:11111111111111111111111111111111


    二、例题详解

    1、右移(>>)

    将操作符左边的数向右移动指定的位数,从高位开始,统一向右移动指定的位数,前面补0

    那么现在内存中234567>>4的内存写照为:00000000 00000000 00111001 01000100

    同时,在Java中,有-11>>31=-1(即:11111111111111111111111111111111),由此可知,Java编译器对有符号数的处理方法不一样,右移(>>)高位补符号位(算术右移)

    (2)左移(<<)

    将操作符左边的数向左移动指定的位数

    现在内存中234567<<4的内存写照为:00000000 00111001 01000100 01110000

    (3)java中number & 0xff什么解释?

    &是“与”运算,如果对应的两个bit都是1,则那个bit的结果为1,否则为0;比如 1010 & 1101 = 1000(二进制)

    0xff是十六进制形式,转换为二进制就是1111 1111,由于0xff的低8位是1,因此number中低8位&之后,如果原来是1,结果位还是1,如果原来是0,结果位还是0,高于8位的,0xff都是0,所以无论原来是0还是1,结果位都是0;所以,如果number为0xabcd,那么number & 0xff = 0xabcd  & 0x00ff=0x00cd = 0xcd

    参考资料

    (1)http://nassir.iteye.com/blog/1994914

    (2)一个算法题引出的异或运算律

    http://blog.virtao.org/articles/163.html

    (3)优秀程序员不得不知道的20个位运算技巧

    http://www.cnblogs.com/qiaogaojian/p/5873105.html


    网络序字节序

    http://www.cnblogs.com/jacktu/archive/2008/11/24/1339789.html

    http://blog.chinaunix.net/uid-12782-id-2915864.html


    直接摘抄过来 http://blog.163.com/tfn2008@yeah/blog/static/11032131920131211310727/

    在Java中,不存在Unsigned无符号数据类型,但可以轻而易举的完成Unsigned转换。

    方案一:如果在Java中进行流(Stream)数据处理,可以用DataInputStream类对Stream中的数据以Unsigned读取。

    Java在这方面提供了支持,可以用java.io.DataInputStream类对象来完成对流内数据的Unsigned读取,该类提供了如下方法:
    (1)int   readUnsignedByte()    //从流中读取一个0~255(0xFF)的单字节数据,并以int数据类型的数据返回。返回的数据相当于C/C++语言中所谓的“BYTE”。
    (2)int readUnsignedShort()   //从流中读取一个0~65535(0xFFFF)的双字节数据,并以int数据类型的数据返回。返回的数据相当于C/C++语言中所谓的“WORD”, 并且是以“低地址低字节”的方式返回的,所以程序员不需要额外的转换。

    方案二:利用Java位运算符,完成Unsigned转换。

    正常情况下,Java提供的数据类型是有符号signed类型的,可以通过位运算的方式得到它们相对应的无符号值,参见几个方法中的代码:

    public int getUnsignedByte (byte data){      //将data字节型数据转换为0~255 (0xFF 即BYTE)。
    return data&0x0FF;
    }

    public int getUnsignedByte (short data){      //将data字节型数据转换为0~65535 (0xFFFF 即 WORD)。
    return data&0x0FFFF;
    }

    public long getUnsignedIntt (int data){     //将int数据转换为0~4294967295 (0xFFFFFFFF即DWORD)。
    return data&0x0FFFFFFFFl;
    }

  • 相关阅读:
    eclipse常用快捷键
    Android 布局
    Android UI设计
    Android Context 是什么?
    内部类
    手写单例模式
    上课笔记:移动开发新利器-你好,Flutter
    Android Fragment
    Kotlin语言
    Android虚拟机和类加载机制
  • 原文地址:https://www.cnblogs.com/studyLog-share/p/4607034.html
Copyright © 2011-2022 走看看