5

符号付き数値表現をチェックする次の方法は、私のマシンで 2 の補数を正しくチェックしますが、それをチェックするための 1 の補数または符号付きマグニチュード マシンを持っていません。コードは適切に機能しますか? さらに重要なのは、移植性があるかどうかです。

ファイル: 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

ファイル: 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;
}
4

1 に答える 1

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
}

厳密に言えば、符号ビットと同じ意味を使用するというint保証がないため、これはコードと同じことを示しているわけではありません。signed charしかし、(a)真剣に?(b) これは型以上で機能しますが、型intが小さい場合はよりトリッキーになります。unsigned charパディングビットがないことが保証されていますが、signed charそうではありません。CHAR_BIT == 9したがって、(たとえば) 、UCHAR_MAX = 511CHAR_MAX = 127、およびsigned char1 つのパディング ビットを持つことは合法だと思います。次に、コードが失敗する可能性があります。保存された符号付き値の符号ビットは、必ずしも期待する場所にあるとは限らず、パディング ビットの値は 0 または 1 のいずれかになる可能性があります。

多くの場合int8_t、代わりにプログラムで使用できますsigned char。存在する場合は 2 の補数であることが保証されているため、 の表現を気にする必要がなくなる可能性がありますsigned char。それが存在しない場合、プログラムはコンパイルされませassertん。2 の補数であるが、8 ビットの文字を持たないため、提供しないプラットフォームから偽陰性が得られますint8_t。これはあなたを悩ませるかもしれませんし、気にしないかもしれません...

于 2011-11-09T13:21:51.040 に答える