C #: как сдвигать бит шестнадцатеричных цифр - PullRequest
4 голосов
/ 11 марта 2010

Хорошо, я работаю над программой игры в карты и храню значения карт в виде шестнадцатеричных цифр. Вот массив:

 public int[] originalCards = new int[54]
        {
            0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
            0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D,
            0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D,
            0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D,
            0x50, 0x51
        };

Первая цифра относится к масти (1 = пики; 2 = клюшки; .... 5 = джокеры) Вторая цифра - это номер карты (1 = туз, 5 = 5; 13 = K и т. Д.).

Я хотел бы сделать что-то вроде следующего: </p> <p>Pseudocode:</p> <pre><code> public int ReturnCard(int num) { int card = currentDeck[num]; int suit = card.firsthexdigit; int value = card.secondhexdigit; return 0; }

Мне не нужен новый метод для работы с целыми числами, я просто включил его для ясности.

Кто-нибудь знает, как это сделать в C #?

Редактировать: Хорошо, я использую сдвиг битов, как описано в одном из ответов. Я могу получить вторую цифру (костюм) просто отлично, но первая цифра продолжает выходить как «0». Есть идеи почему?

Редактировать: редактировать: хорошо, теперь работает нормально. Спасибо, ребята.

Ответы [ 5 ]

5 голосов
/ 11 марта 2010

Вы на самом деле не "разбираете" как таковой, просто выполняете некоторые простые битовые манипуляции.

int card = currentDeck[num];
int suit = (card & 0xF0) >> 4;
int value = card & 0x0F;

Будет делать то, что вы хотите.

3 голосов
/ 11 марта 2010

Чтобы ответить на ваш вопрос об использовании 0xF0 и 0x0F в примере сдвига битов, то, что они делают, это поразрядно И .Когда вы делаете card & 0xF0, то, что вы делаете, и вводите два значения, это приводит к установке всех битов, кроме 4, которые вас интересуют, в 0.Пример:

 0x48   01001000     0x48   01001000
&0x0F  &00001111    &0xF0  &11110000
-----   --------     ----   --------
 0x08   00001000     0x48   01000000 >> 4
                            --------
                            00000100
3 голосов
/ 11 марта 2010

Вот ответ с использованием битовых полей.

struct {
    unsigned int suit:4;
    unsigned int value:4;
} card    = currentDeck[num];
int suit  = card.suit;
int value = card.value;

Вам может понадобиться добавить int для заполнения как первое или последнее поле, чтобы правильно расположить биты. Битовые поля обычно используются для доступа к оборудованию, потому что аппаратные регистры часто упаковывают несколько флагов в один байт.

Кстати, если вы используете сдвиг битов, вы хотите сдвинуть их на количество бит в шестнадцатеричной цифре. Одна шестнадцатеричная цифра содержит значения 0 - 15 или 0 - F, для этого требуется 4 бита, а не 8. Поэтому это следует использовать:

int suit = (card & 0xF0) >> 4;
1 голос
/ 11 марта 2010

Вот рабочий пример:

using System;

namespace Test
{
    class MainClass
    {
        static int[] currentDeck = new int[54] {
                0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
                0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D,
                0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D,
                0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D,
                0x50, 0x51 };

        static void printParts (int num)
        {
            int card  = currentDeck[num];
            int suit  = (card & 0xF0) >> 4;
            int value = (card & 0x0F);

            Console.Out.WriteLine(
                    String.Format ("Card: {0:x4},   ", card) +
                    String.Format ("Suit: {0:x4},   ", suit) +
                    String.Format ("Value: {0:x4}", value ));
        }


        public static void Main (string[] args)
        {
            printParts(  7 );
            printParts( 18 );
            printParts( 30 );
            printParts( 48 );
        }
    }
}

Это производит следующее:

Card: 0018,   Suit: 0001,   Value: 0008
Card: 0026,   Suit: 0002,   Value: 0006
Card: 0035,   Suit: 0003,   Value: 0005
Card: 004a,   Suit: 0004,   Value: 000a

Я не уверен, почему ваши верхние цифры не верны.

1 голос
/ 11 марта 2010

Вы можете попробовать

int card = originalCards[1];
int suit = card /16;
int value = card % 16; 
...