причина этого проста: последовательность с 0 и сложением.
Вы хотите прибавление работать так же для положительных и отрицательных чисел без особых случаях ... в частичном, увеличивающиеся -1 на 1 должен уступить 0.
Единственная последовательность битов, где классическое приращение перелива выдает значение 0, это последовательность в 1 бит. Если вы увеличиваете на 1, вы получаете все нули. Так что ваши -1: все 1s, то есть побитовое отрицание 0. Теперь мы (предполагая, что 8-битовые целые числа, увеличивающиеся на 1 в каждой строке)
-2: 11111110 = ~1
-1: 11111111 = ~0
0: 00000000 = ~-1
+1: 00000001 = ~-2
Если вам не нравится такое поведение, вам нужно кроме того, для обработки особых случаев, и вы будете иметь +0 и -0. Скорее всего, такой процессор будет намного медленнее.
Если ваш вопрос как
int i = -j;
реализован, это зависит от компилятора и процессора и оптимизации. Обычно он будет оптимизирован вместе с другими указанными вами операциями. Но не удивляйтесь, если это заканчивается тем, что были выполнены в
int i = 0 - j;
Так как это, вероятно, занимает 1-2 процессора клещей для вычисления (например, в качестве одного XOR
или регистра на себя, чтобы получить 0, то SUB
операцию вычислить 0-j
), это едва ли станет узким местом. Загрузка j
и сохранение результата i
где-то в памяти будет намного дороже. На самом деле, некоторые процессоры (MIPS?) Даже имеют встроенный регистр, который всегда равен нулю. Тогда вам не нужна специальная инструкция для отрицания, вы просто вычитаете j из $zero
обычно в 1 тик. Говорят, что нынешние процессоры Intel распознают такие операторы xor и делают их в 0 тиках, с оптимизацией переименования регистров (т. Е. Они позволяют следующей инструкции использовать новый регистр, который равен нулю). У вас есть neg
на amd64, но быстрый xor rax,rax
полезен и в других ситуациях.
Это математическая истина. Аппаратное обеспечение выполняет побитовое отрицание и приращение/декрементирование; для этих операций обычно предусмотрены инструкции по единой сборке. Хотя я бы поспорил, что современные процессоры также имеют инструкции более высокого уровня, которые компиляторы воспользуются ... – qxz
Это не «ответственность», это всего лишь следствие представления двухкомпонента. Битовый шаблон '00000000 ... 0' означает' 0', бит-шаблон '11111111 ... 1' означает' -1'. – Barmar
Часть процессора, реализующего арифметику, знает, как работает представление. Когда вы умножаете число на '-1', это приводит к дополнению + add1. – Barmar