二进制基本原理

<pre name="code" class="java">package test;
/** 
 * @Classname: Binary 
 * @Description: TODO 二进制 
 * @Author: chenn_xu@sina.cn 
 * @Date: 2015年10月22日 上午11:11:18 
 * @Version:V1.0 
 *  
 * 本篇代码阐述:二进制基本原理、反码、补码、及其计算机如何运算 
 *      基本原理: 
 *          在java中的int数据类型占4个字节 
 *          计算机里每个字节=8位 
 *          从右到左,由低位到高位,逢2进1;最高位为符号位(0代表正数,1代表负数);java没有无符号数; 
 *              int i = -2 ;原码:10000000000000000000000000000010 
 *              int i = -1 ;原码:10000000000000000000000000000001 
 *              int i = 1 ;原码:00000000000000000000000000000001 
 *              int i = 2 ;原码:00000000000000000000000000000010 
 *              int i = 3 ;原码:00000000000000000000000000000011 
 *              int i = 4 ;原码:00000000000000000000000000000100 
 *          Binary.getIntByOriginalCode(code);模拟实现将java中int数据类型的原码转为数值 
 *          Binary.getOriginalCode(number);模拟实现通过java中int数据获取的对应的原码 
 *      反码: 
 *          正数的反码:等于原码; 
 *          0的反码:等于原码; 
 *          负数的反码:最高位符号位不变,其他位去反; 
 *          Binary.getReversalByOriginalCode(code);模拟实现通过java中int数据获取的对应的反码 
 *      补码: 
 *          正数的补码:等于原码; 
 *          0的反码:等于原码; 
 *          负数的反码:等于反码+1 
 *          Binary.getComplementByOriginalCode(code);模拟实现通过java中int数据获取的对应的补码 
 *      计算机计算: 
 *          都是通过反码进行计算的(ps:结果也是补码)   
 *          如:2-1=1;(计算机进行加减时都是通过加的方式)2+(-1) 
 *              2的原码:00000000000000000000000000000010   
 *              2的补码:00000000000000000000000000000010 
 *              -1的原码:10000000000000000000000000000001 
 *              -1的补码:11111111111111111111111111111111 
 *               
 *                      00000000000000000000000000000010 
 *                  +   11111111111111111111111111111111 
 *                  —————————————————————————————————————— 
 *                  =   00000000000000000000000000000001(这也是补码)原码:00000000000000000000000000000001 = (数值)1(正数的补码是原码,so不变) 
 *             二进制加法:1+1
 *				原码:
 *				00000000000000000000000000000001
 *				00000000000000000000000000000001
 *				补码:
 *				00000000000000000000000000000001
 *				00000000000000000000000000000001
 *				________________________________
 *				00000000000000000000000000000010 = 2
 *				
 *				二进制减法:1-2
 *				原码:
 *				00000000000000000000000000000001
 *				10000000000000000000000000000010
 *				补码:
 *				00000000000000000000000000000001
 *				11111111111111111111111111111101
 *				————————————————————————————————
 *				11111111111111111111111111111110
 *				原码:
 *				10000000000000000000000000000001 - -1
 *				
 *				二进制乘法:5*7
 *				00000000000000000000000000000101
 *				00000000000000000000000000000111
 *				————————————————————————————————
 *				00000000000000000000000000000101
 *				0000000000000000000000000000101
 *				000000000000000000000000000101
 *				————————————————————————————————
 *				00000000000000000000000000100011 = 2的5次方+2的1次方+1 = 32 +2 +1 =35
 *				
 *				二进制除法:35/5
 *				00000000000000000000000000100011
 *				00000000000000000000000000000101
 *				
 *						    111 = 2的2次方 + 2的1次方+ 1 = 4+2+1 = 7
 *					____________________________
 *				101 | 	100011
 *						 101
 *						 ____________________________
 *						  1111
 *						  101
 *						  ____________________________
 *						   101
 *						   101
 *						   ____________________________
 *						     0
 *      java 位运算符: 
 *              取反(~):不管正数还是负数、符号位,统统反向  ps:取反后也是补码 
 *              按位与(&):两个为1才为1,否则为0 (两原码按位比较)
 *              按位或(|):1个为1为1,否则为0 (同理)
 *              异或(^):两个不同才取1,否则为0
 *              算数左移(<<):<span style="font-family: Arial, Helvetica, sans-serif;">符号位不变,低位补零</span>
 *              算数右移(>>):<span style="font-family: Arial, Helvetica, sans-serif;">低位溢出,符号不变,并用符号位补溢出来的高位</span>
 *              逻辑右移(>>>):低位溢出,高位补零
 */  
public class Binary {  
    public static void main(String[] args) {  
        try {  
            System.out.println(getOriginalCode(-8));  
            System.out.println(-8>>>2);
            //转为数值   
            System.out.println(Binary.getIntByOriginalCode("00111111111111111111111111111111"));  
            //转为原码  
            //System.out.println("1:"+Binary.getOriginalCode(1)); 
            //System.out.println("2:"+Binary.getOriginalCode(2));  
            //System.out.println("3:"+Binary.getOriginalCode(3));  
            //System.out.println("4:"+Binary.getOriginalCode(4));  
            //转反码  
            //System.out.println(Binary.getReversalByOriginalCode("10000000000000000000000001000000"));  
            //转补码  
            //System.out.println(Binary.getComplementByOriginalCode("00000000000000000000000001000000"));  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
      
    //根据原码获取补码  
    public static String getComplementByOriginalCode(String code)throws Exception{  
        if (code==null || code.length()!=32  || getFrequency(code,"1")+getFrequency(code,"0")!=32) {  
            throw new Exception("非法java>int数据类型二进制原码,请检查字符串!");  
        }  
        //正数的补码是等于原码  
        if (code.substring(0,1).equals("0")) {  
            return code;  
        }  
        //负数的补码:补码的反码加1  
        String[] $code = getReversalByOriginalCode(code).split("");  
        for (int i = $code.length-1; i >=1 ; i--) {  
            if (i == $code.length-1) {  
                if ($code[i].equals("0")) {  
                    $code[i]="1";  
                    break;  
                }  
                $code[i]="0";  
                continue;  
            }  
            if ($code[i].equals("0")) {  
                $code[i]="1";  
                break;  
            }  
            if (i==1) {  
                throw new Exception("该二进制长度超出java>int存储范围!");  
            }  
        }  
        StringBuffer complement = new StringBuffer();  
        for (int i = 1; i < $code.length; i++) {  
            complement.append($code[i]);  
        }  
        return complement.toString();  
    }  
      
    //根据原码获取反码  
    public static String getReversalByOriginalCode(String code)throws Exception{  
        if (code==null || code.length()!=32  || getFrequency(code,"1")+getFrequency(code,"0")!=32) {  
            throw new Exception("非法java>int数据类型二进制原码,请检查字符串!");  
        }  
        //正数的反码是等于原码  
        if (code.substring(0,1).equals("0")) {  
            return code;  
        }  
        //负数的反码:最高位符号位不变  
        StringBuffer complement = new StringBuffer();  
        String[] $code = code.split("");  
        for (int i = 1; i < $code.length; i++) {  
            if (i==1) {  
                complement.append("1");  
                continue;  
            }  
            complement.append($code[i].equals("1")?"0":"1");  
        }  
        return complement.toString();  
    }  
      
      
    /** 
     *  
     * @Methodname: getOriginalCode 
     * @Discription: TODO 获取int数据在计算机中的原码 
     * @param i 
     * @return 原码 
     *  
     */  
    public static String getOriginalCode(int number)throws Exception{  
        String[] code ="00000000000000000000000000000000".split("");  
        String[] locations = getLocation(Math.abs(number)).split(",");  
        for (int i = 0; i < locations.length; i++) {  
            int location = 32-Integer.parseInt(locations[i]);  
            if (location >= 32) {  
                break;  
            }  
            code[location+1] = "1";  
        }  
        if (number<0) {  
            code[1]= "1";  
        }  
        StringBuffer originalCode = new StringBuffer();  
        for (int i = 1; i < code.length; i++) {  
            originalCode.append(code[i]);  
        }  
        return originalCode.toString();  
    }  
      
      
    private static String getLocation(int number)throws Exception{  
        if (number == 0) {  
            return "-1";  
        }  
        for (int i = 1; i < 32; i++) {  
            if (Math.pow(2, i-1)==number) {  
                return String.valueOf(i);  
            }  
            if (Math.pow(2, i-1)<number && Math.pow(2, i)>number) {  
                return String.valueOf(i)+","+getLocation(number-(int)Math.pow(2, i-1));  
            }  
        }  
        throw new Exception("超出java>int数据类型二进制原码二进制存储范围!");  
    }  
    /** 
     *  
     * @Methodname: getIntByOriginalCode 
     * @Discription: TODO 根据原码获取数值 
     * @param code 原码 
     * @return 数值 
     * @throws Exception 
     * remark: 
     *      求原码公式:累加2的(位数-1)次方, ps:从低位开始算位数 
     * 
     */  
    public static int getIntByOriginalCode(String code)throws Exception{  
        if (code==null || code.length()!=32  || getFrequency(code,"1")+getFrequency(code,"0")!=32) {  
            throw new Exception("非法二进制原码,请检查字符串!");  
        }  
        int _int = 0;//结果  
        int index = 0;//位置  
        while ((index=code.indexOf("1",index+1))!=-1) {  
            _int += Math.pow(2,32-index-1);  
        }  
        return code.substring(0,1).equals("1")?0-_int:_int;  
    }  
      
    /** 
     *  
     * @Methodname: getFrequency 
     * @Discription: TODO 获得特定字符串在另外字符串中出现的频率 
     * @param base 字符串 
     * @param str 特定字符串 
     * @return 出现的次数 
     * 
     */  
    private static int getFrequency(String base,String str){  
        int fromIndex = -2;  
        int frequency = 0;  
        while ((fromIndex=base.indexOf(str, fromIndex==-2?0:fromIndex+1))!=-1) {  
            frequency++;  
        }  
        return frequency;  
    }  
}  

 

public static void main(String[] args) {

		/**
		 * 非位运算
		 * (所有位取返)
		 */
		// 
		// 1111 1111 1111 1111 1111 1111 1111 1110
		// 0000 0000 0000 0000 0000 0000 0000 0001 结果:1
		System.out.println(~-2);
		
		/**
		 * 异或运算
		 * (相同则结果为0,不同则结果为1)
		 */
		// 1111 1111 1111 1111 1111 1111 1111 1101
		// 1111 1111 1111 1111 1111 1111 1111 1110
		// 0000 0000 0000 0000 0000 0000 0000 0011 结果:3
		System.out.println(-3^-2);
		
		/**
		 * 或运算
		 * (两个位只要有一个为1,那么结果就是1,否则就为0)
		 */
		// 1111 1111 1111 1111 1111 1111 1111 1101
		// 1111 1111 1111 1111 1111 1111 1111 1110
		// 1111 1111 1111 1111 1111 1111 1111 1111
		// 结果解析
		// 1111 1111 1111 1111 1111 1111 1111 1110
		// 1000 0000 0000 0000 0000 0000 0000 0001	结果:-1	
		System.out.println(-3|-2);
		

		/**
		 * 与运算
		 * (两个位都为1,结果才为1,否则结果为0)
		 */
		// 1111 1111 1111 1111 1111 1111 1111 1101
		// 1111 1111 1111 1111 1111 1111 1111 1110
		// 1111 1111 1111 1111 1111 1111 1111 1100
		// 结果解析
		// 1111 1111 1111 1111 1111 1111 1111 1011
		// 1000 0000 0000 0000 0000 0000 0000 0100	结果:-4	
		System.out.println(-3&-2);

		/**
		 * 左位移运算
		 */
		// 1111 1111 1111 1111 1111 1111 1111 1101

		// 1111 1111 1111 1111 1111 1111 1111 1010
		// 结果解析
		// 1111 1111 1111 1111 1111 1111 1111 1001
		// 1000 0000 0000 0000 0000 0000 0000 0110	结果:-6
		System.out.println(-3<<1);

		/**
		 * 右移位运算
		 */
		// 1111 1111 1111 1111 1111 1111 1111 1101

		// 1111 1111 1111 1111 1111 1111 1111 1110
		// 结果解析
		// 1111 1111 1111 1111 1111 1111 1111 1101
		// 1000 0000 0000 0000 0000 0000 0000 0010	结果:-2
		System.out.println(-3>>1);
		

		/**
		 * 无符号右移位运算
		 */
		// 1111 1111 1111 1111 1111 1111 1111 1101

		// 0111 1111 1111 1111 1111 1111 1111 1110
		// 0111 1111 1111 1111 1111 1111 1111 1110
		System.out.println(-3>>>1);
		System.out.println(Integer.toBinaryString(2147483646));
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值