The following way of checking for the signed number representation checks for twos complement correctly on my machine, but I dont have ones complement or signed magnitude machines to check it. Would the code work properly and more importantly, is it portable?
File: 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;
}
I think you’re better off just masking the bits of a negative
int:Strictly speaking, this doesn’t tell you the same thing as your code, since there’s no guarantee that
intandsigned charuse the same meaning of the sign bit. But (a) seriously? and (b) this works for typesintand larger, for smaller types it’s trickier.unsigned charis guaranteed to have no padding bits, butsigned charis not. So I think it’s legal to have (for example)CHAR_BIT == 9,UCHAR_MAX = 511,CHAR_MAX = 127, andsigned charhas 1 padding bit. Then your code could fail: the sign bit in the stored signed value isn’t necessarily where you expect it to be, and the value of the padding bit could be either 0 or 1.In a lot of cases you could just use
int8_tin the program instead ofsigned char. It’s guaranteed to be 2’s complement if it exists, so might save you from caring about the representation ofsigned char. If it doesn’t exist, the program won’t compile, which is kind of what you’reasserting anyway. You’d get a false negative from platforms which are 2’s complement, but don’t have an 8-bit char and therefore do not provideint8_t. This may or may not bother you…