Пусть a будет переменной целочисленного типа со знаком T, а U - соответствующим беззнаковым типом. Выражение (U)a дает значение, соответствующее представлению в дополнении до двух значения a как U. Я хочу знать, гарантирует ли стандарт C следующее, чтобы отменить это приведение. Быть u типа U и иметь значение (U)a. Be MAX максимальное значение, которое может содержать тип T. (Помните о неявных преобразованиях в типы без знака и о том факте, что каждое положительное значение переменной со знаком остается неизменным при этих преобразованиях.)
Во-первых, предположим, что T может хранить результат:
T convert_2scomplement_to_T(U n) {
return n<=MAX ? n : -(T)(U)-n;
}
Во-вторых, допустим, функция должна обнаружить такой недопустимый аргумент; быть MIN минимальное значение T может содержать:
T convert_2scomplement_to_T_checked(U n) {
if(n <= MAX) return n;
if( !(n & (U)1 << sizeof(U)*CHAR_BIT-1) ) { // (*)
// invalid argument, the value is positive and `T' cannot hold it
}
/* `n' represents something negative if we're here. */
if(-n < MIN) {
// invalid argument, the value is negative and `T' cannot hold it
}
return -(T)(U)-n;
}
Строка, отмеченная // (*), насколько я могу судить, не является строго соответствующей, потому что стандарт не дает никаких гарантий относительно положения бита знака.
Описанные функции работают должным образом? И можно ли избежать проверки бита знака в строго соответствующем коде?
(И помимо языкового юриста… было бы здорово, если бы кто-то, кто написал код, зная, что хотя бы один человек использовал его на платформе, не использующей дополнение до двух, мог бы оставить комментарий, что это была за машина. Википедия упоминает
величина со знаком:
дополнение:
- https://en.wikipedia.org/wiki/PDP-1
- https://en.wikipedia.org/wiki/CDC_160_series
- https://en.wikipedia.org/wiki/UNIVAC_1100/2200_series
но, похоже, в программах, написанных сегодня, об этом не стоит беспокоиться. Есть ли причина, по которой стандарт все еще касается таких машин?)
(U)aв целом, просто укажите, что вместо добавления 2 к 2 - person M.M   schedule 03.07.2014-1? Вы не можете ответить на этот вопрос, не зная ширины типа. Допустим,intимеет 1 бит знака, 15 битов значения и 16 бит заполнения; аunsigned intимеет 32 бита значения. Тогда дополнение до двух для-1будет0xFFFF, но(U)aбудет0xFFFFFFFF. Итак, на самом деле вы имеете в виду представление в дополнении 2 значенияa, но где используемая ширина - это ширинаU. Это кажется ненужным отвлечением, когда вы можете просто написать(U)a, что совершенно однозначно. - person M.M   schedule 03.07.2014T func(U)так, чтобыt == func(t)для всехt?, или что-то еще. - person M.M   schedule 03.07.2014unsigned char). - person mafso   schedule 03.07.2014char) целочисленных типов без знака. Я тоже не знаю, есть ли соответствующие части стандарта, дающие больше ограничений на беззнаковые представления… - person mafso   schedule 03.07.2014