int getMax(int a, int b) {
int c = a - b;
int k = (c >> 31) & 0x1;
int max = a - k * c;
return max;
}
Давайте рассмотрим это. Эта первая строка кажется простой - в ней хранится разница a
и b
. Это значение отрицательно, если a < b
, и неотрицательно в противном случае. Здесь на самом деле ошибка - если разница чисел a
и b
настолько велика, что не может вписаться в целое число, это приведет к неопределенному поведению - упс! Итак, давайте предположим, что здесь этого не происходит.
В следующей строке, которая
int k = (c >> 31) & 0x1;
Идея состоит в том, чтобы проверить, является ли значение c
отрицательным. Практически во всех современных компьютерах числа хранятся в формате, называемом дополнением до двух , в котором старший бит числа равен 0, если число положительное, и 1, если число отрицательное. Кроме того, большинство целых 32-битных. (c >> 31)
сдвигает число на 31 бит вниз, оставляя старший бит числа в месте для младшего бита. Следующий шаг - взять это число и сложить его с 1 (двоичное представление которого равно 0 везде, кроме последнего бита) стирает все старшие биты и просто дает вам младший бит. Поскольку младший бит c >> 31
является старшим битом c
, это означает, что старший бит c
считывается как 0 или 1. Поскольку старший бит равен 1, тогда как c
равно 1, это проверка, является ли c
отрицательным (1) или положительным (0). Сочетая это рассуждение с вышеприведенным, k
равно 1, если a < b
, и 0, в противном случае.
Последний шаг - сделать это:
int max = a - k * c;
Если a < b
, то k == 1
и k * c = c = a - b
, и так
a - k * c = a - (a - b) = a - a + b = b
Какой максимальный максимум, так как a < b
. В противном случае, если a >= b
, то k == 0
и
a - k * c = a - 0 = a
Что также является правильным макс.