简体   繁体   中英

C checking for signed number representation

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: 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;
}

I think you're better off just masking the bits of a negative 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
}

Strictly speaking, this doesn't tell you the same thing as your code, since there's no guarantee that int and signed char use the same meaning of the sign bit. But (a) seriously? and (b) this works for types int and larger, for smaller types it's trickier. unsigned char is guaranteed to have no padding bits, but signed char is not. So I think it's legal to have (for example) CHAR_BIT == 9 , UCHAR_MAX = 511 , CHAR_MAX = 127 , and signed char has 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_t in the program instead of signed char . It's guaranteed to be 2's complement if it exists, so might save you from caring about the representation of signed char . If it doesn't exist, the program won't compile, which is kind of what you're assert ing 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 provide int8_t . This may or may not bother you...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM