Двоичные константы на макросах
От: Ka3a4oK  
Дата: 19.06.06 10:11
Оценка:
#include <stdlib.h>
#include <iostream>

// Переводит беззнаковое целое в строку "бинарного вида".
// Примечание: нереентерабельная
const char* b2str(unsigned a)
{
    static char buff[256]="0000000000000000000000000000000"; //31 ноль в начале

    // Не уверен, что _ultoa есть везде
    return &buff[0]+strlen(_ultoa(a, &buff[31], 2))-1;
}

#define ZERO_OR_FAIL(cnd)\
    (0/((cnd)?1:0))

#define EXT(b, i)\
    ((b>>i*3)&(1<<i))

#define CMPS(b)\
    (\
    EXT(b, 0)|\
    EXT(b, 1)|\
    EXT(b, 2)|\
    EXT(b, 3)|\
    EXT(b, 4)|\
    EXT(b, 5)|\
    EXT(b, 6)|\
    EXT(b, 7)\
    )

#define _B2(b3, b2, b1, b0)\
    ZERO_OR_FAIL((b3|0x11111111)==0x11111111)+\
    ZERO_OR_FAIL((b2|0x11111111)==0x11111111)+\
    ZERO_OR_FAIL((b1|0x11111111)==0x11111111)+\
    ZERO_OR_FAIL((b0|0x11111111)==0x11111111)+\
    (CMPS(b3)<<24)|(CMPS(b2)<<16)|(CMPS(b1)<<8)|(CMPS(b0))

// Переводит 4 шестнадцатеричные константы "бинарного вида" в беззнаковое целое.
// Постарался сделать максимальную статическую защиту. В случаяе нарушения формата
// возникнет ошибка времени компиляции: деление на 0.
#define B2(b3, b2, b1, b0)\
    ZERO_OR_FAIL(sizeof(#b3)==9)+\
    ZERO_OR_FAIL(sizeof(#b2)==9)+\
    ZERO_OR_FAIL(sizeof(#b1)==9)+\
    ZERO_OR_FAIL(sizeof(#b0)==9)+\
    _B2(0x##b3, 0x##b2, 0x##b1, 0x##b0)


int main(int argc, char* argv[])
{
    // Использование
    const unsigned int i(B2(00000000,10111000,10000110,10001111));

    std::cout<<b2str(i)<<std::endl;

    return 0;
}



Понадобилось работать с двоичным представлением числа: определять константы двоичного вида и выводить переменные в двоичном виде. Вот моя поделка. На шаблонах можно было бы сделать элегантнее, красивее, безопаснее, но на препроцессоре забавнее
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.