5

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

文件:平台.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

文件:ac

#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;
}
4

1 回答 1

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
}

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

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

于 2011-11-09T13:21:51.040 回答