【发布时间】:2011-12-25 06:40:14
【问题描述】:
以下检查有符号数表示的方法在我的机器上正确检查二进制补码,但我没有补码或有符号幅度机器来检查它。代码能否正常工作,更重要的是,它是否可移植?
文件:平台.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;
}
【问题讨论】:
-
你必须非常努力才能找到一台不使用补码的计算机。我怀疑过去 20 到 30 年在学术界以外制造的任何计算机都没有它。
-
我不是 100%,但我相信存储有符号整数并将其作为无符号整数访问是实现定义或未定义的行为。有关按位运算符,请参阅 C99 6.5 §4:“这些运算符产生的值取决于整数的内部表示,并且具有符号类型的实现定义和未定义方面。”据我了解,这个工会也必须如此。
-
@Lundin:您可以将其作为
unsigned访问(这是严格别名规则所允许的类型之一),但除非int的值可以表示为unsigned(即不是负数),不能保证它不是unsigned的陷阱值。所以它不是 100% 可移植的,但问题不是一般访问有符号的 int,而是特别是访问-1。 -
@steve 我的印象是
char类型不会有这样的问题,因为C 保证不会有填充位。不存在字节序问题。 C 保证存在值位的 1-1 映射。所以剩下的唯一问题是符号位是否映射到无符号的值位。鉴于 signed 和 unsigned char 必须具有相同的宽度,因此必须如此。 (话虽如此,我同意你的回答更好) -
我不同意“有符号和无符号字符必须具有相同的宽度”。它们使用相同的存储,但这并不意味着它们具有相同数量的填充位。当然,除非我错过了标准中的某个地方,即
signed char没有填充。
标签: c platform negative-number representation