Операции uint8_t, когда они переполняются?

Я не уверен, когда мне нужно беспокоиться о переполнении при использовании неподписанных символов. Этот случай ясен:

uint8_t a = 3;
uint8_t b = 6;
uint8_t c = a - b; // c is 253

Однако что здесь происходит:

float d = a - b; // d is -3

Являются ли оба a и преобразованы в float перед выполнением вычитания?

Или также в этом случае:

float e = (a - b) + (a - c);

Все три переменные преобразованы в число с плавающей точкой?

Возможны ли случаи переполнения, даже если назначаемая переменная является плавающей точкой? Правила одинаковы, если е это float, или int, или что-нибудь еще?

Кроме того, что происходит в таком случае:

int a = std::abs(a - b);

2

Решение

Ваш случай не является результатом преобразования char-to-float, но обусловлен целочисленными правилами продвижения.
Cppreference утверждает следующее (выделение мое):

Значения малых целочисленных типов (таких как char) могут быть преобразованы в значения больших целых типов (таких как int). Особенно, арифметические операторы не принимают типы, меньшие чем int, в качестве аргументов, и интегральные продвижения автоматически применяются после преобразования lvalue в rvalue, если это применимо. Это преобразование всегда сохраняет значение.

А также:

unsigned char или unsigned short могут быть преобразованы в int, если они могут содержать весь диапазон значений, и unsigned int в противном случае.

Так что в вашем случае - Оператор преобразует значения в целые числа, которые затем конвертируются в числа с плавающей точкой. Только назначение c преобразует обратно в uint8_t (который переполняет).

То же самое относится к std::abs пример: значения преобразуются перед вычитанием, а результат передается в функции.

Для получения дополнительной информации о подписанных / неподписанных продвижениях по арифметическим операциям, смотрите, например, этот ответ: https://stackoverflow.com/a/6770275/3198247

5

Другие решения


По вопросам рекламы [email protected]