У меня есть метод манипуляции бит, который умножает число на пять восьмых, и если есть раунды остатков в направлении 0. Метод работает, и я понимаю почти все из этого. Однако, когда я его просматривал, я понял, что не уверен, что 7 (00000111) учитывает ошибку округления, в которой она будет округлять к более отрицательному числу вместо 0, и мне нужно понять, почему эта линия работает. Насколько я могу судить, переключение multiplyByFive на 31 бит вправо будет просто проверять знак переменной и выводить все, если отрицательный, поэтому, если он равен 7, либо будет давать все нули, если положительный, или y в двоичном, если отрицательный. Если мое понимание правильное, почему добавление этого значения в multiplyFiveEighths и деление суммы на 8 вокруг отрицательного числа вниз, без ошибок.Бит Манипуляция - Понимание округления к нулевому смещению при умножении отрицательного на фракцию
int multFiveEights(int x) {
разбить его на умножение на 5 и последующее деление на 8 сдвиге это два влево умножает его на четыре, плюс й делает его на 5
int multiplyByFive = (x << 2) + x;
если результат является отрицательным, и 2^31 = 7, прежде чем сдвиг вправо
int addNumber = 7 & (multiplyByFive >> 31);
11111111 (если вы сдвиг вправо на 31, когда отрицательный вы получаете все 1s)
вернет все 0s, если положительные и 1 в LSB, если отрицательный
добавление 7 к multiplyByFive счета за ошибки
если его отрицательный, он будет пытаться округлить, который идет в сторону более отрицательного числа, так Андинг его с 7 счетов для этой ошибки/тесты для остатка
int fiveEigths = (multiplyByFive + addNumber) >> 3;
return fiveEigths;
Если 'x' положительный, то вы понимаете, почему' x/8' округляется вниз, но '(x + 7)/8' округляется? – immibis