Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

[С#, VS2008] Ошибка при конвертации битового массива в байт

38K
25 апреля 2010 года
EqKeeper
94 / / 19.02.2010
Доброго времени суток! Возникла проблема, а я никак не могу найти - в чем причина. Надеюсь на вашу помощь!

Есть байт. Есть флажок, повешенный на 1 и 2 биты. Нужно получить и изменить его значение. Вначале с true на false, затем обратно.

Я превращаю байт в массив битов. Изменяю нужные. Затем превращаю обратно в байт. С false все проходит. С true возникает проблема... Вот код:

Код:
// Конвертация массива бит в байт
public static class BitExt
{
    public static byte ToByte(this BitArray bits)
    {
        byte result = 0;
        for (byte index = 0, m = 1; index < 8; index++, m *= 2)
            result += bits.Get(index) ? m : (byte)0;
        return result;
    }
}

// Собственно байт, битами которого оперируем
private byte _b = (byte)203; // 11001011

// Оболочка для работы с битами
public bool bit
{
    get { return ((_b & 3) != 0); }
    set
    {
        BitArray bits = new BitArray(_b);
        bits[0] = value;
        bits[1] = value;
        _b = bits.ToByte();
    }
}


Пытаюсь с этим работать:
 
Код:
bit; // => true
bit = false;
bit; // => false
bit = true; // вылетает с ошибкой


Отладчик матерится на метод:
public static byte ToByte(this BitArray bits)

Говорит, что index выходит за пределы диапазона. index в этот момент равен 7. А длина битового массива... тоже семи. И вот, собственно, вопрос: куда девается восьмой бит? :confused:

P.S. А, может. мой подход и вовсе в корне не верный и можно проще, лучше? Тогда подскажите - как? Все это безобразие творится внутри структуры и в C++ писалось не в пример проще, а тут я весь в сомнениях...
5
25 апреля 2010 года
hardcase
4.5K / / 09.08.2005
Зачем все НАСТОЛЬКО усложнять?

Флаги:
 
Код:
[Flags]
public enum DataBits : byte {
    First = 1,
    Second = 2
}

            var x  = DataBits.First | DataBits.Second;
            Console.WriteLine((byte)x);
            Console.WriteLine(x);


Побитовые операции:
 
Код:
byte x = 0;

x |= 1; // поднимаем первый бит
x |= 2; // поднимаем второй бит

x &= ~1; // сбрасываем первый бит
x &= ~2; // сбрасываем второй бит
253
25 апреля 2010 года
Proger_XP
1.5K / / 07.08.2004
Хм, может я не чего-то не понял, но чем вас не устраивают обычные битовые операторы вроде & и |?
 
Код:
char b;
b = 0;  // => false
b = b | 1; // #0=false; #1=true
b = b | 2; // #0=true; #1=true
b = b & 2; // #0=false; #1=true
b = b ^ 1; // #0=true; #1=true
// и т.д.


p.s: hardcase синхронно :)
38K
26 апреля 2010 года
EqKeeper
94 / / 19.02.2010
Хех. Всем устраивают. Большое спасибо! Действительно, переборщил. :)
38K
26 апреля 2010 года
EqKeeper
94 / / 19.02.2010
Хм....
x &= ~1;
x &= ~2;
Не проходит и гнусно матерится:
Постоянное значение "-2" не может быть преобразовано в "byte"
Он почему-то вместо инверсии бит делает число отрицательным...

---

Пробовал и так, в чистом виде. И написав функцию для работы с битами:
x |= (1 << i); // Установить бит i
x &= ~(1 << i); // Сбросить бит i
Результат один и тот же. Ставить ставит. А сбрасывать не хочет.

---

Руководствуясь нехитрой логикой, заменил "1" в сбросе на -1. Вроде бы, все заработало правильно. Теперь я буду бесконечно благодарен тому, кто объяснит мне - почему именно так, а не иначе, и с каких пор байт у нас стал знаковым. С отрицательными двоичными числами у меня вообще разговор особый, но хотелось бы понять что я только что сделал и к чему это приведет...
5
26 апреля 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: EqKeeper
Хм....
x &= ~1;
x &= ~2;
Не проходит и гнусно матерится:
Постоянное значение "-2" не может быть преобразовано в "byte"
Он почему-то вместо инверсии бит делает число отрицательным...

Так сделайте его байтом :)

 
Код:
unchecked {
   ...
    x &= (byte) ~2;
   ...
}
Отрицательное число и есть - инверсия бит. Учим матчасть.
38K
27 апреля 2010 года
EqKeeper
94 / / 19.02.2010
Большое спасибо. В байт я его пытался конвертнуть, но про блок unchecked не знал. За матчасть спасибо, наконец разобрался с отрицательными числами в бинарной системе. :)
38K
27 апреля 2010 года
EqKeeper
94 / / 19.02.2010
Все работает.
Вопрос: а можно прикрутить к байту вышеозначенные формулы для работы с битами?
byte b = 4;
b.bits[0] = true; b.bits[1] = false;

Пробовал реализовать это при помощи методов расширения, но кроме вороха ошибок ничего толкового не добился. =\

А работать это должно примерно так:
Код:
class byte
  public bool bits
  {
    get
    {
       if ((this & (1<<INDEX)) == 0) {return false;} else {return true;}
    }
    set
    {
       uncheced{
         if (value) {this |= (1<<INDEX);} else {this &= (byte) ~(1<<INDEX);}
       }
    }
  }

Где INDEX - индекс в массиве бит.
Можно реализовать?
5
27 апреля 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: EqKeeper
Все работает.
Вопрос: а можно прикрутить к байту вышеозначенные формулы для работы с битами?


А зачем если есть формулы? Ну или на худой конец enum с флагами.

5
27 апреля 2010 года
hardcase
4.5K / / 09.08.2005
Цитата: hardcase
А зачем если есть формулы? Ну или на худой конец enum с флагами.


Код:
using System;

namespace flags
{
    [Flags]
    enum ByteFlags : byte {
        Zero = 0,
        All = 255,
        b0 = 1,
        b1 = 2,
        b2 = 4,
        b3 = 8,
        b4 = 16,
        b5 = 32,
        b6 = 64,
        b7 = 128,
    }

    class Program
    {
        private static void Print(ByteFlags flags) {
            Console.WriteLine("Flags: {0}, Value: {1}", flags, (byte) flags);
        }
       
        public static void Main(string[] args)
        {
            var b = ByteFlags.Zero;

            Print(b);
            b |= ByteFlags.b2;
            b |= ByteFlags.b5;
            Print(b);

            b ^= ByteFlags.All;
            Print(b);
           
            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }
    }
}
38K
28 апреля 2010 года
EqKeeper
94 / / 19.02.2010
Еще раз большое спасибо! :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог