Преобразование в поведение подписанного типа при выходе за пределы допустимого диапазона
Преобразование целого числа в тип со знаком, когда исходное значение не может быть представлено в целевом типе, соответствует cppreference.
- определяется реализацией (до C++20)
- уникальное значение целевого типа, равное исходному значению по модулю 2^n , где n — количество битов, используемых для представления целевого типа (начиная с C++20)
Также указано в поведении, определяемом реализацией GCC , существует
Для преобразования в тип ширины N значение уменьшается по модулю 2^N , чтобы быть в пределах диапазона типа; сигнал не поднимается.
Я думаю, там говорят то же самое. Мой вопрос заключается в том, не может ли уменьшенный/модульный результат выйти за пределы диапазона целевого подписанного типа? Сказать
signed char c = 255
, 255 по модулю 2^8 по-прежнему равно 255 без изменений. Как этот модульный результат вписывается в целевой тип?
В этом ответе показан способ сначала инвертировать значение и добавить 1, а затем добавить бит со знаком. Я не уверен, что это действительно было сделано.
Как правильно/стандартно интерпретировать выделенную часть?
2 ответа
Ни одна из этих кавычек не означает, что берется исходное значение, применяется операция по модулю и результат используется как результат преобразования.
Вместо этого они предназначены для того, чтобы сказать, что из всех значений, представляемых в целевом типе, (уникальное) то, для которого выполняется математическое равенство
s + m * 2^n = v
выполняется для некоторого целого числа
m
, с исходным значением. Он сказал, что
s
а также
v
конгруэнтны по модулю , если они удовлетворяют этому условию, а иногда также равны по модулю
2^n
.
За
s = 255
с подписанной целью ширины
8
,
255
не представим, а
-1
есть и
v = -1
удовлетворяет уравнению с
m = -1
.
Скажем, подписанный char = 255U, 255 по модулю 2 ^8 по-прежнему 255.
255 не находится в пределах диапазона типа (8-битного целого числа со знаком).
Один из способов перефразировать правило состоит в том, что преобразованный результат будет соответствовать непредставимому результату по модулю 2^n.
-513, -257, -1, 255, 511 конгруэнтны по модулю 256. Из конгруэнтных чисел только -1 находится в пределах представляемого диапазона знакового типа.