C检查签名号码表示

时间:2011-11-09 12:13:30

标签: c platform negative-number representation

以下检查签名号码表示的方法在我的机器上正确检查二进制补码,但是我没有补码或签名幅度机器来检查它。代码是否正常工作,更重要的是,它是否可移植?

文件:platform.h

#ifndef PLATFORM_H
#define PLATFORM_H
#include <limits.h>

static
const union {
    signed char sc;
    unsigned char uc;
} plat_4xvYw = {.sc = -1};

#define IS_TWOS_COMPL (plat_4xvYw.uc == UCHAR_MAX)
#define IS_ONES_COMPL (plat_4xvYw.uc == UCHAR_MAX - 1)
#define IS_SIGNED_MAG (plat_4xvYw.uc == (1U << (CHAR_BIT - 1)) + 1U)

#endif

档案:a.c

#include <inttypes.h>
#include <limits.h>
#include "platform.h"
#include <assert.h>

int
main (void) {

    assert (IS_TWOS_COMPL);
    if (IS_TWOS_COMPL) {

        printf ("twos complement\n");
    } else if (IS_ONES_COMPL) {

        printf ("ones complement\n");
    } else if (IS_SIGNED_MAG) {

        printf ("signed magnitude\n");
    }
    return 0;
}

1 个答案:

答案 0 :(得分:5)

我认为你最好只掩盖负面int

if ((-1 & 0x1) == 0) {
    // -1 ends in "0" => 1s' complement
} else if ((-1 & 0x2) == 0) {
    // -1 ends in "01" => sign-magnitude
} else {
    // -1 ends in "11" => two's complement
}

严格来说,这并不能告诉您与代码相同的内容,因为无法保证intsigned char使用符号位的相同含义。但(a)认真对待? (b)这适用于int和更大的类型,对于较小的类型,它更棘手。保证unsigned char没有填充位,但signed char不是。所以我认为(例如)CHAR_BIT == 9UCHAR_MAX = 511CHAR_MAX = 127signed char有1个填充位是合法的。那么你的代码可能会失败:存储的有符号值中的符号位不一定是你期望的那样,并且填充位的值可以是0或1。

在很多情况下,您只能在程序中使用int8_t而不是signed char。如果它存在,它保证是2的补码,因此可以避免关心signed char的表示。如果它不存在,程序将无法编译,这无论如何都是assert。你会从2位补码的平台得到假阴性,但没有8位字符,因此不提供int8_t。这可能会或可能不会打扰你...