Я использую 64-битную Mac OS X, у меня есть NSUInteger (или uint64, это не имеет значения в моей системе).
Как получить старшие 20 бит NSUInteger и сохранить его в другом NSUInteger?
Вы можете ответить, как это сделать на C, C ++ или Objective-C.
Постскриптум Пожалуйста, не говорите мне изменять весь код и использовать вместо этого битовые поля.
P.P.S. Я думаю, я должен использовать битовую маску и сдвиг?
Для uint64_t вы можете просто использовать
i >> 44
Для типов со знаком или типов, размер которых может превышать 64 бита, вам также необходимо маскировать старшие биты.
(i >> 44) & 0xFFFFF
Пример меньшего масштаба,
4 bits starting at pos 2 of 8.
7 6 5 4 3 2 1 0
+---+---+---+---+---+---+---+---+
| ? | ? | j | ? | ? |
+---+---+---+---+---+---+---+---+
>> 2
+---+---+---+---+---+---+---+---+
| * | * | ? | ? | j | * = 0 if unsigned or original bit7 if signed.
+---+---+---+---+---+---+---+---+
& ( 2**4 - 1 )
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | j |
+---+---+---+---+---+---+---+---+
uint64 original = ...;
uint64 another = ((0xFFFFF00000000000 & original) >> 44);
Сначала и с битовой маской, затем двигайтесь вправо на 44 бита.
Я не знал о проблеме с переключением сначала для подписанных номеров. Это зависит от реализации? Кажется, это не имеет большого значения, если вы меняете до или после подписанного или неподписанного для моей реализации:
int main()
{
uint64_t a = std::numeric_limits<uint64_t>::max();
int64_t b = std::numeric_limits<int64_t>::max();
uint64_t c = std::numeric_limits<uint64_t>::max();
int64_t d = std::numeric_limits<int64_t>::max();
a = (0xFFFFF00000000000 & a) >> 44;
b = (0xFFFFF00000000000 & b) >> 44;
c = 0xFFFFF & (c >> 44);
d = 0xFFFFF & (d >> 44);
cout << "a = " << a << "; c = " << c << "; a?=c = " << (a==c) << endl;
cout << "b = " << b << "; d = " << b << "; b?=d = " << (b==d) << endl;
return 0;
}
Это производит:
a = 1048575; c = 1048575; a?=c = 1
b = 524287; d = 524287; b?=d = 1
$ c++ --version
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix