C检查签名号码表示

tyt*_*yty 4 c platform representation negative-number

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

文件: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
Run Code Online (Sandbox Code Playgroud)

档案: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;
}
Run Code Online (Sandbox Code Playgroud)

Ste*_*sop 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
}
Run Code Online (Sandbox Code Playgroud)

严格地说,这并没有告诉你与代码相同的东西,因为不能保证intsigned 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.这可能会或可能不会打扰你......