В ролях подписано, чтобы уже подписано - PullRequest
0 голосов
/ 27 ноября 2018

Если тип назначения подписан, значение не изменяется, если исходное целое число может быть представлено в типе назначения.

Если я правильно понимаю, гарантируется ли, что:

static_cast<std::int8_t>(static_cast<std::int16_t>(-3)) == -3

?

Поскольку -3 может быть представлен в std :: int8_t.

Таким образом, в примере дополнения до двух s:

Затем в примере функции дополнения до двух нужно ли промежуточное преобразование в std :: uintmax_t?

#include <type_traits>

template <typename T>
T twos_complement(T val)
{
    typedef std::make_unsigned<T>::type U;

    return static_cast<T>(-static_cast<uintmax_t>(static_cast<U>(val)));
}

, потому что применяется

return static_cast<T>(-static_cast<U>(val));

интегральное повышениеперед унарным минусом может "испортить эффект приведения к типу без знака, если T уже, чем int"?

Ответы [ 3 ]

0 голосов
/ 27 ноября 2018

Адаптация кода, который вы связали с C ++, приводит:

#include <cstdint>

template <typename T>
T twos_complement(T val)
{
    return static_cast<T>(-static_cast<uintmax_t>(val));
}
0 голосов
/ 27 ноября 2018

Подписанные / неподписанные представления зависят от платформы.Даже если большинство современных платформ используют дополнение двух для представления чисел со знаком, вы не можете сделать это предположение.Использование static_cast для дополнения до двух не является правильным способом.Если вы хотите сделать битовую манипуляцию самостоятельно, используйте типы без знака фиксированного размера, как в ответе Квантового Физика (но учтите, что то, что произойдет в случае переполнения при добавлении, зависит от платформы).

0 голосов
/ 27 ноября 2018

Почему бы вам не получить два дополнения, как это:

uint32_t num = 10;
uint32_t cmp = ~num + 1; // this is two's complement of 10.

Разве это не работает для вас?

РЕДАКТИРОВАТЬ: если вы беспокоитесь, что может произойти переполнение(для подписанного или неподписанного), просто сделайте это сначала:

if(~num == std::numeric_limits<MyIntType>::max()) {
    // overflow mitigation
}

Вы также можете статически проверить, является ли ваш тип подписанным или неподписанным для смягчения проблем переполнения соответствующими способами с std::is_signed и std::is_unsigned.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...