C проверка на представление числа со знаком
Следующий способ проверки подписанных проверок представления чисел для двойок корректно дополняет на моей машине, но у меня нет машин, дополняющих или знаковых величин, чтобы проверить это. Будет ли код работать правильно и, что более важно, переносим ли он?
Файл: 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;
}
1 ответ
Я думаю, что вам лучше просто замаскировать кусочки негатива 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
использовать то же значение знака бита. Но (а) серьезно? и (б) это работает для типов int
и больше, для небольших типов это сложнее. unsigned char
гарантированно не имеет битов заполнения, но signed char
не является. Так что я думаю, что законно иметь (например) CHAR_BIT == 9
, UCHAR_MAX = 511
, CHAR_MAX = 127
, а также signed char
имеет 1 бит дополнения. Тогда ваш код может потерпеть неудачу: бит знака в сохраненном значении со знаком не обязательно там, где вы ожидаете, и значение бита заполнения может быть либо 0, либо 1.
Во многих случаях вы можете просто использовать int8_t
в программе вместо signed char
, Это гарантированно будет дополнением 2, если оно существует, поэтому может избавить вас от заботы о представлении signed char
, Если он не существует, программа не будет компилироваться, что является своего рода assert
в любом случае. Вы получили бы ложный минус от платформ, которые являются дополнением 2, но не имеют 8-битный символ и, следовательно, не предоставляют int8_t
, Это может или не может беспокоить вас...