Продвижение типа данных при арифметических операциях: -1
main() {
if ( -1 < (unsigned char) 1 )
printf("less than");
else
printf("NOT less than");
}
печать less than
. Так, (unsigned char) 1
превращается в (signed char) 1
и затем: (signed) -1 < (signed) 1
, таким образом, выводится less than
.
но если я изменю вышеуказанный код to if ( (-1 < (unsigned int) 1 )
затем выводится NOT less than
.
поэтому очевидно, что когда я меняю unsigned char на unsigned int:
- (signed) -1 преобразуется в unsigned int [происходит прямо противоположное]
- С -1 хранятся в 2 комплимент 1; битовый шаблон оценивается как 255 (вероятно)
- таким образом, 255
- даже если вы замените
int a = -1;
вместо " -1 " тот же результат
вопросы:
во время подписанной и неподписанной арифметики...как убедиться, что signed будет преобразован в unsigned или наоборот.
почему преобразование отличается для арифметики между unsigned char и char: по-видимому, unsigned преобразуется в signed и unsigned int и int: по-видимому, signed преобразуется в unsigned
PS: Я знаю, что это не зависит от компилятора..поэтому не говорите, что это так.
2 ответов
правила таковы:
6.3.1.8 обычные арифметические преобразования
...
в противном случае целочисленные промо-акции выполняются для обоих операндов. Затем к продвигаемым операндам применяются следующие правила:
- если оба операнда имеют один и тот же тип, дальнейшее преобразование не требуется.
- в противном случае, если оба операнда имеют целочисленные типы со знаком или оба имеют целочисленные типы без знака, операнд с типом преобразования меньшего целого ранга преобразуется в тип операнда с большим рангом.
- в противном случае, если операнд с целочисленным типом без знака имеет ранг, больший или равный рангу типа другого операнда, то операнд со знаком целочисленного типа преобразуется в тип операнда с целочисленным типом без знака.
- в противном случае, если тип операнда со знаком, целочисленный тип С может представлять все значения тип операнда с беззнаковый целочисленный тип, затем операнда с беззнаковый целочисленный тип преобразуется к типу операнда с типом integer.
- в противном случае оба операнда преобразуются в целочисленный тип без знака, соответствующий типу операнда с целочисленным типом со знаком.
затем правила работают следующим образом:
-1 < (unsigned char) 1
сначала оба операнда преобразуются в ints (поскольку int может представлять все значения unsigned char). Затем производится сравнение этих типах. Затем используется правило 1. Сравнение успешно.
-1 < (unsigned int) 1
int не может представлять все значения unsigned int, поэтому используется правило 3, и целое число со знаком преобразуется в целое число без знака (UINT_MAX - 1). Сравнение теперь проваливается.
Это связано с целое число акций. Оба аргумента могут быть представлены как int, поэтому они преобразуются в int.
ISO C 6.3.1.1, пункт 2:
Если int может представить все значения исходного типа, значение преобразуется к типу int; в противном случае он преобразуется в unsigned int. Они называются целочисленными специальные акции.48) Все остальные типы являются неизменными целыми акциями.