Interview_C ++ _ day27

Побитовые достигается путем арифметических операций по модулю

  • операция Add

Для каждого из них, в случае без учета бит переноса может быть получено
\ [0 + 0 = 0 + 1 = 1 0 \\ \\ \\ 1 + 1 + 0 = 1 1 = 0 \]
Очевидно, что выше при условии исключающее или операции , и только четвёртый случай произошел перенос, перенос, в соответствии с работы. В переносе на всех, должны быть добавлены на более высоком одном месте, это значение может быть влево оперативной реализации. Тогда это может быть
\ [х + у = х \
oplus у + (х \ & у) << 1 \] можно найти за новой формулы в добавили французский, до тех пор , как она может быть рассчитана рекурсивно. Когда \ ((х \ & у) << 1 == 0 \) , французский добавил устранен.

ll add(ll x, ll y) {
    ll newx = x^y;
    ll newy = (x&y)<<1;
    if(newy == 0)   return newx;
    return add(newx, newy);
}
  • вычитание

Операция Вычитание можно рассматривать как
\ [\ BEGIN {выровнен} -y & = \ сим у + 1 \\ х + у & = х + (- у) \\ & = х + \ сим у + 1 \ {конец выровнен} \ ]
также может быть получено путем добавления французского

ll sub(ll x, ll y) {
    return add(x, add(~y, 1));
}
  • операция умножения

Предположим , что \ (Y = 1010 \) , может быть сосредоточено на бинарных \ (\ 1) битов, то может , (х * у \) \ сделайте разборке
\ [\ {начинают выровненную} х * у = х & * 1010 \\ & = х * 1000
+ X * 0010 \ {конец выровнен} \] , и это только тогда , когда множитель \ (1 \) , то может быть достигнуто с помощью бинарных операций сдвига влево.

ll mul(ll x, ll y) {
    ll ans = 0;
    int flag = x^y;
    x = x<0 ? add(~x, 1) : x;
    y = y<0 ? add(~y, 1) : y;
    for(int i=0; (1ll<<i)<=y; i++) {
        if(y&(1ll<<i)) {
            ans = add(ans, x<<i);
        }
    }
    return flag<0 ? add(~ans, 1) : ans;
}
  • Отдел операций

И я думал , что один и то же операция умножения, перечислить каждый ответ ли \ (1 \) , чтобы получить продукт, слева и вычитать. Начните с большим начать искать, если есть один \ (1 \) , то этот бит установлен в ответ на \ (1 \) .

ll divide(ll x, ll y) {
    ll ans = 0;
    int flag = x^y;
    x = x<0 ? add(~x, 1) : x;
    y = y<0 ? add(~y, 1) : y;
    for(int i=31; i>=0; i--) {
        if(x >= (1ll*y<<i)) {
            ans |= (1ll<<i);
            x = sub(x, 1ll*y<<i);
        }
    }
    return flag<0 ? add(~ans, 1) : ans;
}
  • операция Modulo

Был результат деления, операция по модулю может быть легко достигнуто

ll mod(ll x, ll y) {
    x = x<0 ? add(~x, 1) : x;
    y = y<0 ? add(~y, 1) : y;
    return sub(x, mul(y, divide(x, y)));
}

Почему объект подкласса может быть присвоен родительский объект, а не наоборот

  • Подкласс наследует родительский класс, который содержит часть родительского класса, но также расширение. Если объект дочернего класса присваивается переменным родительский класс, переменный может быть доступно только с использованием класса части подкласса.
  • Если, в свою очередь, если эта переменная подкласс для доступа к переменным-членам расширения, вы не посетить, в результате чего памяти из диапазона.

рекомендация

отwww.cnblogs.com/Jiaaaaaaaqi/p/12526772.html