2016-01-22 5 views
1

Итак, давайте начнем с 32 разрядными целым числом:битой манипуляция на больших целых числах диапазона «Int»

int big = 536855551; // 00011111111111111100001111111111 

Теперь я хочу, чтобы установить последние 10 бит в пределах этого целый:

int little = 69; // 0001101001 

Итак, мой подход был таков:

big = (big & 4294966272) & (little) 

где 4294966272 это первые 22 бита, или 11111111111111111111110000000000 ,

Но, конечно, это не поддерживается, потому что 4294966272 находится вне диапазона int0x7FFFFFFF. Кроме того, это не моя единственная операция. Я также должен быть в состоянии установить биты 11 до 14. Мой подход к этому (с той же проблемой) было:

big = (big & 4294951935) | (little << 10) 

Так с объяснением из пути, вот что я делать, как альтернативные для выше:

1: ((big >> 10) << 10) | (little) 
2: (big & 1023) | ((big >> 14) << 14) | (little << 10) 

Я не чувствую, что моя альтернатива являются лучшим, эффективным способом я мог бы пойти. Есть ли лучшие способы сделать это?

Sidenote: Если C# поддерживает бинарные литералы, '0b', это было бы намного красивее.

Спасибо.

+0

использование BigInteger .....? –

+0

@MitchWheat Это никогда не приходило мне в голову ... Можете ли вы показать мне пример (желательно, как ответ, если он работает, я могу его принять), который будет отражать мои примеры выше? –

+0

https://msdn.microsoft.com/en-us/library/system.numerics.biginteger_operators(v=vs.110).aspx –

ответ

2

4294966272 должно быть действительно -1024, которое представлено как 11111111111111111111110000000000.

Например:

int big = 536855551; 
int little = 69; 
var thing = Convert.ToInt32("11111111111111111111110000000000", 2); 
var res = (big & thing) & (little); 

Хотя, результат всегда будет 0

00011111111111111100001111111111 
& 
00000000000000000000000001101001 
& 
11111111111111111111110000000000 
+0

Мне это нравится, потому что я могу определить маски как константы, и это выглядит красиво. И он работает точно так же, как мой подход, но с именами. –

2

Бит сдвига обычно быстрее по сравнению с битовой маской сдвига + (то есть, &). У меня есть test case.

Вы должны пойти со своей первой альтернативой.

1: ((big >> 10) << 10) | (little) 

Просто остерегайтесь a little difference между беззнаковым и знаковым int, когда дело доходит до битового сдвига.

В качестве альтернативы вы можете определить big и little как неподписанные. Используйте uint вместо int.

+0

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