1

Тема: Записати число в масив.

Друзі, не можу придумати як записати окремі байти в масив.
Є масив із 8ми комірок і два байти даних що несуть в собі інфу куди що записати. Виглядає все так:

uint32_t array[8]; // масив 32*8
uint8_t addr = 0x00; // номер біта який потрібно змінити у всьому масиві
uint8_t data = 0x00; // дані що потрібно встановити в номері біта

Повинно бути такЖ
https://replace.org.ua/extensions/om_images/img/610e95f146b2f/2l70bkhhok.png
Нажаль не можу в голові укласти як це реалізувати... *WALL*

2 Востаннє редагувалося koala (07.08.2021 17:40:35)

Re: Записати число в масив.

А нащо аж так криво його записувати?
Хоча, звісно, в першому наближенні

for(uint8_t i=0;i<7;++i)
{
    array[i] &= ~(1<<addr); //clear bit
    array[i] |= data & (1<<addr); //set from data
}

має спрацювати.

Подякували: Si4karuk, leofun012

3 Востаннє редагувалося ReAl (07.08.2021 17:13:40)

Re: Записати число в масив.

koala написав:

А нащо аж так криво його записувати?

Якась 1-бітова графіка, але бітмап повернутий відносно того, що треба писати в буфер?

koala написав:

Хоча, звісно, в першому наближенні

for(uint8_t i=0;i<7;++i)
{
    array[i] &= ~(1<<i); //clear bit
    array[i] |= data & (1<<i); //set from data
}

має спрацювати.

Ні, так буде по діагоналі.

Окрім того, у завданні біти нумеровані з 0 по 32, тобто 33 біти в слові. А addr = 0x04 на картинці показує на 3-тій біт, якщо рахувати з 0.
Якщо addr нумерує біти з 0.

for(uint8_t i=0;i<7;++i)
{
    array[i] &= ~(1<< addr); //clear bit
    array[i] |= !!(data & (1<<i)) << addr; //set from data
}

Але краще наробити макросів для бітів в дусі лінуксових неатомарних.
BIT_MASK, BIT_WORD і взагалі все, що bold -- мають лінки на місця де зустрічаються (ну й де визначені)

Подякували: ch0r_t, Si4karuk, leofun013

4

Re: Записати число в масив.

Я не зрозумів. Масив містить 32*8=128 бітів. А на малюнку, схоже, 33*8=136 бітів. Де саме ще 8 мають знаходитися?

5 Востаннє редагувалося ch0r_t (07.08.2021 17:34:14)

Re: Записати число в масив.

Перестав думати про все це після четвертого прочитання закоментованого рядку:

// дані що потрібно встановити в номері біта
Подякували: Si4karuk1

6

Re: Записати число в масив.

ReAl написав:
for(uint8_t i=0;i<7;++i)
{
    array[i] &= ~(1<< addr); //clear bit
    array[i] |= !!(data & (1<<i)) << addr; //set from data
}

Копіпаст з редагуванням — зло.
Бо так має бути компактніше і швидше на більшості архітектур. І зрозуміліше.

for(uint8_t i=0;i<7;++i)
{
    array[i] &= ~(1<< addr); //clear bit
    array[i] |= (data & 0x01) << addr; //set from data
    data >>= 1;
}

Хоча десь можу бути краще так

bitmask = 1 << addr;
for(uint8_t i=0;i<7;++i)
{
    if (data & 0x01)
        array[i] |= bitmask;
    else
        array[i] &= ~bitmask;
    data >>= 1;
}

Бо той if утопчеться в умовні пропуски команд і, наприклад, на Cortex-M3 тіло циклу буде

.L4:
    ldr    r2, [r3]       @ temp = *ptr
    tst    r0, #1         @ flag = (data & 0x01) != 0
    ite    ne             @ if (flag)
    orrne    r2, r2, r1   @ then temp |= bitmask
    andeq    r2, r2, lr   @ else temp &= ~bitmask;
    str    r2, [r3]       @ *ptr = temp
    adds    r3, r3, #4    @ ++ptr
    cmp    ip, r3         @ flag = (ptr == &array[8])
    lsr    r0, r0, #1     @ data >>= 1
    bne    .L4            @ if (flag) goto start of cycle
Подякували: ch0r_t, Si4karuk, leofun013

7

Re: Записати число в масив.

Помилився поки малював. Бітів 32 а addr 0x03.

8

Re: Записати число в масив.

Так я теж зсуви не ті написав. Уже виправив.

Подякували: Si4karuk1

9

Re: Записати число в масив.

І знову привіт. Все те питання мене бентежить  *DONT_KNOW*
Якщо я можу записати дані в масив, то як мені усереднити цю процедуру?
Тобто скажімо десять разів прилетів біт, то записали, а ні то не записали... %)

Ось код за яким виставляються біти в масиві.

Прихований текст
uint32_t array[8];
uint8_t bitNum = 0;
uint8_t data = 0;

for (int i = 0; i < 8; i++)
                {
                    if (data & (0x01 << i))
                    {
                        array[i] |= (0x01 << bitNum[1]);

                    }
                    else
                    {
                        array[i] &= ~(0x01 << bitNum[1]);
                    }
                }

потрібно зробити якийсь масив лічильників для кожного біту і якщо лічильник дорахував до певної кількості то біт записати в масив. Але для кожного біту це 32*8=256  :o
Що, реально робити 256 лічильників? Чи може щось підкажете? *DONT_KNOW* 

uint8_t counterAverage[256]

10

Re: Записати число в масив.

Очевидно, що з такою умовою - так, потрібно 256 лічильників. Хоча, звісно, вони можуть бути по 4 біти (а якщо зовсім скрутно - то по 3 лічильники на 10 біт).

Подякували: Si4karuk1

11

Re: Записати число в масив.

Якщо для кожного біта потрібно незалежно рахувати кількість і порівнювати з порогом, то нікуди не дінешся — потрібні незалежні лічильники для кожного біта.
А що, сильно тисне обсяг оперативної пам'яті?

Який діапазон цього "скажімо"? 8-16-32... ?
Якщо максимум 16, то можна покрутитися зі зберіганням двох лічильників у одному байті, піде 128 байт, а не 256,
Якщо максимум 8, то може мати сенс зробити "вериткальні лічильники", тоді вистачить 32 * 3 (біти на лічильник) = 96 байт, але складніший код, особливо для вирішення того, що порогу досягнуто -- у прикладі там приходить бітова маска з багатьма бітами і лічильники оновлюються всі разом.

А взагалі пора згадати про правило 5 із заміною "чому" на "навіщо",
потім починати оптимізувати шлях розв'язку, а не кінцеву точку одного з шляхів.

Подякували: Si4karuk, koala, leofun013

12

Re: Записати число в масив.

Клятий шматок ла..на!!! *WALL* Оптимізував, оптимізував і довиоптимізовувався!!!