如何检查数字是二进制还是 C 中的 2 的补码?

How to check whether a number is binary or 2's complement in C?

我当时只使用逻辑门在 C 中制作了一个二进制加法器。现在,例如,我想添加 4 + (-5),这样我就可以得到 2 的补码形式的答案,然后将其转换为十进制。同样,如果我这样做,4 + (-3) 我会得到二进制的答案,并想使用相同的函数将其转换为十进制。

现在,我知道如何将一个2的补码数转换成十进制数,将二进制数转换成十进制数。但我想使用相同的函数将 2 的补码和二进制都转换为十进制。为此,我必须弄清楚数字是二进制的还是 2 的补码。这就是我卡住的地方。

谁能给我一个想法、算法或 C 代码来判断一个数是 2 的补码还是普通二进制?

源代码

筹码

// Author: Ashish Ahuja
// Date created: 8-1-2016
// Descriptions: This file stores all the chips for
//               the nand2tetris project.
// Links: www.nand2tetris.org
//        class.coursera.org/nand2tetris1-001
// Files needed to compile successfully: ourhdr.h

int not (unsigned int a) {
    if (a == 1) {
          return 0;
    }
    else if (a == 0) {
          return 1;
    }
}

int and (unsigned int a, unsigned int b) {
    if (a == 1 && b == 1)
          return 1;
    else if ((a == 1 && b == 0) || (a == 0 && b == 1) || (a == 0 && b == 0))
          return 0;
}

int nand (unsigned int a, unsigned int b) {
    unsigned int ans = 10;
    ans = and (a, b);
    unsigned int ack = not (ans);
    return ack;
}

int or (unsigned int a, unsigned int b) {
    return (nand (not (a), not (b)));
}

int nor (unsigned int a, unsigned int b) {
    return (not (or (a, b)));
}

int xor (unsigned int a, unsigned int b) {
    unsigned int a_r;
    unsigned int b_r;
    unsigned int sra;
    unsigned int srb;
    a_r = not (a);
    b_r = not (b);
    sra = nand (a_r, b);
    srb = nand (b_r, a);
    return nand (sra, srb);
}

int xnor (unsigned int a, unsigned int b) {
    return (not (xor (a,b)));
}

Ourhdr.h

include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <math.h>
#include <time.h>
#include <stdbool.h>
#include <termios.h>
#include <stddef.h>
#include <sys/types.h>
#include <my/signal.h>
#include <my/socket.h>
#include <my/io.h>
#include <my/lib.h>
#include <my/tree.h>
#include <my/bits.h>
#include <my/binary.h>
//#include <my/error.h>

#define MAXLINE 4096
#define BUFF_SIZE 1024

注意:我只会显示这个项目需要的headers。所以就认为其他headers没有用。

将数组转换为整数的函数

int array_num (int arr [], int n) {
    char str [6] [2];
    int i;
    char number [13] = {'\n'};
    for (i = 0; i < n; i ++)
        sprintf (str [i], "%d", arr [i]);
    for (i = 0; i < n; i ++)
        strcat (number, str [i]);
    i = atoi (number);
    return i;
}

获取 int 的位的函数,以及 return 指向包含位的数组的指针

int *get_bits (int n, int bitswanted) {
    int *bits = malloc (sizeof (int) * bitswanted);
    int k;
    int mask;
    int masked_n;
    int thebit;
    for (k = 0; k < bitswanted; k ++) {
        mask = 1 << k;
        masked_n = n & mask;
        thebit = masked_n >> k;
        bits [k] = thebit;
    }
    return bits;
}

二进制转十进制的函数,vice-versa

int convert_num (int n, int what) {
    int rem;
    int i;
    int binary = 0;
    int decimal = 0;

    switch (what) {
        case 0:                    // Convert decimal to binary
             i = 0;
             rem = 0;
             while (n != 0) {
                   rem = n % 2;
                   n /= 2;
                   binary += rem * i;
                   i *= 10;
             }
             return binary;
             break;
        case 1:                   // Convert binary to decimal
             i = 0;
             rem = 0;
             while (n != 0) {
                   rem = n % 10;
                   n /= 10;
                   decimal += rem*pow (2, i);
                   i ++;
             }
             return decimal;
             break;
    }
}

主程序设计

注意: nand2tetris 项目是在 hdl 中完成的,但我很熟悉用 C 来完成它。另外,我拥有的许多功能上述内容摘自 Whosebug。虽然,设计是我自己的。

两者都是二进制。区别是 signedunsigned。对于 >0 这是一样的。对于<0,只要看最高位就可以看出它是一个负数。通过查看最高位可以很容易地使用相同的输出函数,如果它被设置为输出'-'并将负二进制补码转换为它的abs(),这可以很容易地按位完成。

注意:如果一个正数大到可以设置最高位,它就无法再与负二进制补码区分开来。这就是为什么编程语言为此需要单独的类型(例如在 C intunsigned 中)。

关于 2 补码的有趣事实 - 其应用如此广泛的原因是:

For addition you don't need to know if it is negative or positive. Just add as unsigned.

Subtraction is similar, but you have to negate the second operand (see below).

您可能唯一需要关心的是溢出。为此,您必须检查结果的符号是否实际上可以由两个输入的符号和从 pre-most 到最高位的 addition-overflow 产生。

int n 的否定由 0 - n 简单地完成。或者,您可以反转所有位并添加 1 - 这就是 CPU 或硬件减法器基本上所做的。

请注意,2 的补码二进制文件具有不对称范围:-(N+1) ... N

转换时,只要检查最小值(必须单独处理)直接输出,否则取符号(if ( n < 0 ))取反值(n = -n)最后转换-then unsigned/positive - 字符串或字符流的值。