Вокруг целого числа к ближайшему интервалу, который ниже, чем или равен ему и несколько из 64

Учитывая целое число x, как Вы возвратили бы целое число y, который ниже, чем или равен x и нескольким из 64?

7
задан idealistikz 5 May 2010 в 02:01
поделиться

6 ответов

Просто и это с инверсией битов (64-1):

x = x & ~63
// 64  is 000...0001000000
// 63  is 000...0000111111
// ~63 is 111...1111000000

Это в основном очищает младшие шесть бит, что аналогично округлению до кратного 64. Имейте в виду. что это будет округляться к отрицательной бесконечности для отрицательных чисел, а не к нулю, но, похоже, это то, что требует ваш вопрос.

Вы можете увидеть поведение здесь в этом варианте, кратном четырем:

#include <stdio.h>
int main (void) {
    int i;
    for (i = -10; i <= 10; i++) {
        printf ("%3d -> %3d\n", i, i & ~3);
    }
    return 0;
}

Это дает:

-10 -> -12
 -9 -> -12
 -8 ->  -8
 -7 ->  -8
 -6 ->  -8
 -5 ->  -8
 -4 ->  -4
 -3 ->  -4
 -2 ->  -4
 -1 ->  -4
  0 ->   0
  1 ->   0
  2 ->   0
  3 ->   0
  4 ->   4
  5 ->   4
  6 ->   4
  7 ->   4
  8 ->   8
  9 ->   8
 10 ->   8

Имейте в виду, что это работает только для степеней двойки (например, 2 6 = 64) и два дополнения (стандарт ISO не требует такого представления - см. здесь для подробностей - но я никогда не видел среду C, которая не использует его, и я работал на системах от самых маленьких 8051 до самых больших мэйнфреймов). Если вы хотите использовать в качестве делителя любое другое число, вам, вероятно, следует использовать соответствующие математические функции, такие как floor .

17
ответ дан 6 December 2019 в 06:13
поделиться

Предполагая, что вам нужно ближайшее такое целое число и что вы работаете с положительными числами:

x = x / 64 * 64;

Различные битовые хаки выглядят интересно, но в данном конкретном случае в них нет абсолютно никакой необходимости.

2
ответ дан 6 December 2019 в 06:13
поделиться

Для целых чисел без знака

return 0

Для целых чисел со знаком

return floor(-MAXINT/64)*64

; -)

1
ответ дан 6 December 2019 в 06:13
поделиться

(x >> 6) << 6
Сначала сдвигается 6 бит вправо, затем влево - младшие биты заполняются нулями.
Нет проблем со знаком

РЕДАКТИРОВАТЬ: Я думаю, что большинство компиляторов оптимизируют x / 64 * 64 (и любое деление / умножение с малой степенью 2) до тот же код, так что нет необходимости в такой битовой магии, пока вы не захотите, чтобы ваш код выглядел действительно круто :)

(АндрейT считает, что для простого кода есть даже лучшие оптимизации, прочтите комментарии к его сообщению )

3
ответ дан 6 December 2019 в 06:13
поделиться

Где x - число, которое вы хотите округлить до ближайшего кратного n, метод, который вам нужен:

floor(x / n) * n

который вы можете очень хорошо реализовать на C++ (в отличие от C):

int n = 5;
for (int x = 0; x < 100; x++)
    cout << x << " -> " << (x / n) * n << endl;
5
ответ дан 6 December 2019 в 06:13
поделиться
int y = x;
while ( y % 64 )
    y--;
1
ответ дан 6 December 2019 в 06:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: