Сегодня я нашел следующее:
#include <stdio.h>
int main(){
char x = 255;
int z = ((int)x)*2;
printf("%d\n", z); //prints -2
return 0;
}
Так в основном я получаю переполнение, потому что предел размера определяется операндами на правой стороне = знак??
Почему не делает кастинга его к интервалу перед умножающейся работой?
В этом случае я использую символ и интервал, но если я использую "долго" и "долгое длинное целое" (c99), затем я получаю подобное поведение. Это обычно отговаривается от выполнения арифметики с операндами различных размеров?
char
может быть подписанным или беззнаковым, в зависимости от вашего компилятора.
В вашем случае он выглядит подписанным, а 255 находится за пределами диапазона, который он может представлять (вероятно, он может представлять только числа от -128 до 127).
Таким образом, проблема возникает, когда вы назначаете 255 переменной char
- это приводит к значению, определяемому реализацией, которое в вашем случае оказывается равным -1.
Когда вы умножаете -1 на 2, вы получаете -2. Никакой загадки. Приведение к (int)
ничего не делает - типы более узкие, чем int
, всегда повышаются до int
или unsigned int
перед выполнением любых вычислений. с ними.
Другие ответы хорошо объясняют, как ваш пример «работает», поэтому я не буду это снова объяснять.
Однако позвольте мне заметить, что если вы хотите использовать «8-битное целое число без знака», просто используйте
uint8_t
уже (и его 16, 32, 64-битные компаньоны) и держитесь подальше от всех char
s, short
s и int
s в этом мире.
Похоже этот символ подписан на вашей платформе. Таким образом, char x = 255
фактически то же самое, что char x = -1
. Приведение к int не имеет значения.
Попробуйте изменить это на:
unsigned char x = 255;
Нет, вы не получаете переполнение во второй строке (умножение). Проблема в том, что ваш компилятор по умолчанию использует signed char
и 255 переполнений, что означает -1. По сути, вы инициализируете переменную x
значением -1. Преобразование -1 в int приведет к -1 ( подписанные
операнды будут расширены знаком в восходящем преобразовании, тогда как беззнаковые
операнды будут расширены нулем).
Вы можете заставить char
быть беззнаковым
, добавив префикс беззнаковый
]:
unsigned char x = 255;