欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

原码反码补码详解与十进制转换为二进制的各种实现

程序员文章站 2022-03-08 15:30:04
...

原码反码补码详解

在计算机中,为了方便计算(计算机中只有加法运算),所有数字都是用其补码表示的
原码、反码和补码详解:

int类型的表示范围是 [-2^31, 2^31-1]

  1. 正整数,表示范围是 [1, 2^31-1]
    正整数的原码 = 反码 = 补码

  2. 负整数(不能超出表示范围 [-2^31, -1])
    负整数的原码,求负整数绝对值的原码,并将(最左边、最高位)符号位设置为 1
    负整数的反码,在原码的基础上,符号位不变,其余取反
    负整数的补码,在其原码的基础上,符号位不变,其余取反,最后加 1(或者表述为,在负整数的反码基础上,加 1)
    负整数的补码转化为反码,负整数的补码减 1
    负整数的反码转化为原码,符号位不变,其余取反

  3. 零,表示 0
    和正整数一样,其原码 = 反码 = 补码,为 [0000 0000 0000 0000]

注意:
8 位二进制整数的取值范围是 [1111 1111, 0111 1111],也即是 [-127, 127],那么-128怎么表示呢?

对于8位二进制,使用原码或反码表示的范围为[-127, +127],而使用补码表示的范围是 [-128, 127]
(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]补 + [1000 0001]补 = [1000 0000]补
-1-127的结果应该是 -128,在用补码运算的结果中,[1000 0000]补就是 -128。

但是注意因为实际上使用以前的-0的补码来表示-128,所以 -128 并没有原码和反码表示。
(对 -128 的补码表示[1000 0000]补算出来的原码是[0000, 0000]原,这是不正确的)


十进制转换为二进制的三种实现

/**
 * 将一个十进制整数转换为二进制字符串
 *
 * @param n 十进制整数
 * @return 二进制字符串
 */
private static String getBinString1(int n) {
    boolean isNegative = false;
    if (n < 0) {
        isNegative = true;
        n = -1 * n;
    }
    StringBuilder sBuilder = new StringBuilder();
    while(n != 0){
        int remainder = n % 2;
        n = n / 2;
        sBuilder.append(remainder);
    }

    // 根据负数绝对值的原码,计算负数的补码
    if (isNegative){
        for (int i = sBuilder.length(); i < 31; i++)
            sBuilder.append(0);
        sBuilder.append(1);

        for (int j = 0; j < sBuilder.length()-1; j++){
            char ch = sBuilder.charAt(j)=='0' ? '1' : '0';
            sBuilder.setCharAt(j, ch);
        }

        StringBuilder tmpBuilder = new StringBuilder();
        int addition = 1;
        for (int k = 0; k < sBuilder.length(); k++){
            int emt = (sBuilder.charAt(k) == '0' ? 0 : 1) + addition;
            if (emt == 1) {
                tmpBuilder.append(1);
                break;
            }else{
                tmpBuilder.append(0);
                addition = 1;
            }
        }
        for(int i = tmpBuilder.length(); i < sBuilder.length(); i++)
            tmpBuilder.append(sBuilder.charAt(i));
        sBuilder = tmpBuilder;
    }
    return sBuilder.reverse().toString();
}


private static String getBinString2(int number) {
    StringBuilder sBuilder = new StringBuilder();
    int base = 1;
    while(base > 0){
        int bitResult = (number & base) > 0 ? 1 : 0;  // 9 & 8 = 8
        sBuilder.append(bitResult);
        base = base << 1;
    }
    sBuilder.append((number & base) < 0 ? 1 : 0);  // number = 9, 0000 0000 0000 0000 0000 0000 0000 1001
    return sBuilder.reverse().toString();
}


/**
 * 将整型数字转换为二进制字符串
 * @param number 整型数字
 * @return 二进制字符串
 */
private static String getBinString3(int number) {
    StringBuilder sBuilder = new StringBuilder();
    for (int i = 0; i < 32; i++){
        sBuilder.append(number & 1);
        number = number >>> 1;
    }
    return sBuilder.reverse().toString();
}