Как реализуется унарный минус и логическое отрицание?
Нужно сделать переменную с тремя значениями: одно нейтральное и два противоположных, которые можно инвертировать.
Придумал пока такие варианты:
Значения {-1,0,1} и операция инвертирования унарным минусом x=-x.
Значения {0,1,2} и операция инвертирования ксором x=x^255.
В каком случае инверсия будет выполняться быстрее?
Также еще нужно сделать родственную переменную, но нейтральное значение уже не нужно, достаточно два противоположных значения, которые можно инвертировать. Стоит ли делать тип bool или можно взять какую-то из вышеперечисленных структур? Какова машинная реализация операции отрицания для переменной bool? Есть ли у нее преимущества перед вышеперечисленными способами?
Родственную не в смысле классов, а том смысле, что значения переменных изредка будут сравниваться и присваиваться друг другу. Поэтому единая реализация была бы полезна.
С машинной точки зрения нет особой разницы между bool,char и int, просто первые 2 в памяти обычно занимают меньше места. Также операции -x и x^255 выполняются одинаково быстро, то есть тоже никакой разницы.
Кстати, а есть ли разница в скорости от того, сколько байт занимает число? Вдруг современное железо устроено так, что ему удобнее работать с 32\64 разрядными словами, а не с байтами.
Евгений Обыкновенный: Нет. Современное железо пытается вытянуть максимальную производительность из всех возможных вариантов. Массивы всех целочисленных типов встречаются в программах очень часто, поэтому тут им точно нельзя схалтурить. Когда только появились первые x64 процессоры, производительность работы с 64-битными числами была ниже в 2 раза, но и для них теперь операции выполняются за минимально возможное время, то есть 1 такт.
Чем длиннее число, тем больше места оно занимает в кеше-процессора, а он весьма невелик. Если данных нет в кеше, то можете забыть о гигагерцах процессора и разнице с скорости операций. Всё упрётся во время доступа к оперативной памяти. Оптимизация доступа к данным с учётом особенностей работы кеша это настоящая головная боль.
Евгений Обыкновенный: Оптимизацию не забыл включить?
Ибо x ^= 0xff можно реализовать одной операцией
xor byte ptr[x], 0FFh.
Логическое отрицание x = !x;
not byte ptr[x].
Проверка на 0 и НЕ 0, пройдёт успешно. Если нужен именно 0 или 1, то
cmp byte ptr [x], 0
setz [x]
Обычное отрицание x = -x;
neg byte ptr [x].
if ( x == 0 ) y = 1; else y = 0
cmp byte ptr [x], 0
setz byte ptr [y]
Инструкции 2, но про одинаковость я говорил только про x=-x, x ^= 255.