2009-06-16 3 views
1

у меня есть какой-то старый код, как это:бит сдвига путаницы в C#

private int ParseByte(byte theByte) 
{ 
     byte[] bytes = new byte[1]; 
     bytes[0] = theByte; 
     BitArray bits = new BitArray(bytes); 

     if (bits[0]) 
      return 1; 
     else 
      return 0; 
} 

Это долго, и я полагал, что я мог бы обрезать его вниз, как это:

private int ParseByte(byte theByte) 
{ 
     return theByte >> 7; 
} 

Но, я не получаю те же значения, что и первая функция. Байт либо содержит 00000000, либо 10000000. Что мне здесь не хватает? Я использую неправильный оператор?

ответ

4

Проблема в том, что в первой функции биты [0] возвращают младший значащий бит, но вторая функция возвращает самый старший бит. Для того, чтобы изменить вторую функцию, чтобы получить наименьший значащий бит:

private int ParseByte(byte theByte) 
{ 
    return theByte & 00000001; 
} 

Чтобы изменить первую функцию, чтобы вернуть значащий бит, следует использовать биты [7] - не биты [0].

+0

, так что в шестнадцатеричном редакторе я использовал данные, отображаемые как 10000000. Наверное, сначала он отобразил lsb? и мне повезло с моей путаницей в BitArray? – scottm

+0

@ scott2012: Я не могу говорить за ваш шестнадцатеричный редактор, но так работает BitArray - младший бит находится в индексе 0. Вы можете проверить это коротким кодом: var bits = new BitArray (новый байт [] {0xf0}); // 11110000 for (int idx = 0; idx <= 7; idx ++) Console.WriteLine ("{0}: {1}", idx, bits [idx]); –

0

Возможно, первая функция должна проверять биты [7]?

+0

Первая функция получает то, что я хочу, вторая не работает. – scottm

+0

выполняет следующую работу: return ((int) theByte == 128)? 1: 0; –

0

У вас есть дополнительный ноль в двоичных числах (у вас есть 9 цифр в каждом). Я предполагаю, что это просто опечатка.

Вы уверены, что сделали правильный заказ? Binary традиционно написана справа налево, а не слева направо, как и большинство других систем нумерации. Если двоичное число, которое вы указали, имеет свойство форматированное (это означает, что 10000000 действительно номер 128, а не номер 1), тогда ваш первый фрагмент кода не должен работать, а второй должен. Если вы пишете его назад (это означает, что 10000000 - 1, а не 128), тогда вам даже не нужно битрейт. Просто И это с 1 (theByte & 1).

Фактически, независимо от подхода побитовое И (оператор &) представляется более подходящим. Учитывая, что ваша первая функция работает, а вторая - нет, я предполагаю, что вы просто написали номер назад и должны И это с 1, как описано выше.

+0

исправлена ​​опечатка. Я не пишу его назад, это формат для некоторых двоичных данных, которые я читаю. Я не знаю, почему это было сделано именно так. Я попробую и хотя бы – scottm

0

По словам пользователя на Microsoft's site, BitArray внутренне хранит бит в Int32s в бинарном порядке по большому значению. Это может вызвать проблему. Для решения и дополнительной информации вы можете перейти по ссылке.

3

Эквивалентная функция первого snipet является:

return theByte & 1 == 1 

Во втором snipet вы chechink наиболее смысловыми немного и в первом snipet наименее значимый.

0

1st Первая функция не работает, поскольку она пытается вернуть строку вместо int.

Но то, что вы можете это:

private static int ParseByte(byte theByte) 
    { 
     return theByte & 1; 
    } 

Однако вы также можете это:

private static string ParseByteB(byte theByte) 
    { 
     return (theByte & 1).ToString(); 
    } 
+0

Исправлена ​​опечатка – scottm

1

Хотите вернуть INT или строка? В любом случае - вы можете использовать по модулю:

return theByte % 2 == 0 ? "0" : "1" 

OK, вы редактировали ...и хотите вернуть int

Слово для вашей операции переключения: вам нужно будет использовать < < вместо >>. Но это возвращается (если вы приводите в байтах вместо междунар) 0 или 128, а не 0 или 1. Таким образом, вы могли бы переписать второе решение, как:

return (byte)(theByte << 7) == 128 ? 1 : 0; 

Но другие ответы содержат действительно лучшие решения, чем это.

Смежные вопросы