Учитывая целое число x, как Вы возвратили бы целое число y, который ниже, чем или равен x и нескольким из 64?
Просто и
это с инверсией битов (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
.
Предполагая, что вам нужно ближайшее такое целое число и что вы работаете с положительными числами:
x = x / 64 * 64;
Различные битовые хаки выглядят интересно, но в данном конкретном случае в них нет абсолютно никакой необходимости.
Для целых чисел без знака
return 0
Для целых чисел со знаком
return floor(-MAXINT/64)*64
; -)
(x >> 6) << 6
Сначала сдвигается 6 бит вправо, затем влево - младшие биты заполняются нулями.
Нет проблем со знаком
РЕДАКТИРОВАТЬ: Я думаю, что большинство компиляторов оптимизируют x / 64 * 64
(и любое деление / умножение с малой степенью 2) до тот же код, так что нет необходимости в такой битовой магии, пока вы не захотите, чтобы ваш код выглядел действительно круто :)
(АндрейT считает, что для простого кода есть даже лучшие оптимизации, прочтите комментарии к его сообщению )
Где x
- число, которое вы хотите округлить до ближайшего кратного n
, метод, который вам нужен:
floor(x / n) * n
который вы можете очень хорошо реализовать на C++ (в отличие от C):
int n = 5;
for (int x = 0; x < 100; x++)
cout << x << " -> " << (x / n) * n << endl;