以下是检查带符号数表示的方法。在我的机器上,这种方法能够正确地检查二进制补码,但我没有单独的反码或补码机器来进行测试。这段代码能否正常工作,并且更重要的是,它是否具有可移植性?
文件:platform.h
文件: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
File: 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;
}
unsigned
来访问(它是严格别名规则允许的类型之一),但除非int
的值可以表示为unsigned
(即非负数),否则不能保证它不是一个unsigned
的陷阱值。因此,它并不是100%可移植的,但问题并不在于通常情况下访问有符号整数,而在于访问特定的-1
。 - Steve Jessopchar
类型不会有这样的问题,因为 C 保证不会有填充位。没有字节序问题。C 保证值位有一对一的映射。所以唯一的问题是符号位是否映射到无符号值位。鉴于有符号和无符号 char 必须具有相同的宽度,那就必须是这种情况。(话虽如此,我认为你的答案更好) - tyty