Постоянный/литеральный двоичный файл C++

Почему бы не использовать вместо этого одно число и рассчитать все эти валюты из него?

Например, у вас может быть число 4 202 754, и оно заполнит медь 754, серебро 202, золото 4 и драгоценные камни 0.

Например, мы будем хранить это число в B2. Для меди мы будем использовать поле C2 с этим значением: = MOD (B2, 1000) Для серебра мы будем использовать поле D2 с этим значением: = MOD (FLOOR (B2 / 1000, 1), 1000) Для золота мы будем используйте поле D2 с этим значением: = MOD (FLOOR (B2 / 1000000, 1), 1000) Для драгоценных камней мы будем использовать поле D2 с этим значением: = FLOOR (B2 / 1000000000, 1)

13
задан Evan Teran 31 March 2009 в 19:14
поделиться

7 ответов

Это работает, если у Вас есть начальный нуль на Вашем двоичном значении? Начальный нуль делает константу восьмеричной, а не десятичной.

Который приводит к способу сжать пару большего количества цифр из этого решения - всегда запускают Вашу двоичную константу с нуля! Затем замените 10-е в своем шаблоне с 8's.

25
ответ дан 1 December 2019 в 17:55
поделиться

C++ 0x имеет пользовательские литералы, которые могли использоваться для реализации то, о чем Вы говорите.

Иначе я не знаю, как улучшить этот шаблон.

4
ответ дан 1 December 2019 в 17:55
поделиться

Подходы я всегда использовал, хотя не столь изящный как Ваш:

1/Просто используют шестнадцатеричное число. Через некоторое время Вы просто узнаете, который шестнадцатеричные цифры представляют который комбинации двоичных разрядов.

Константы Использования 2/и ИЛИ или ADD их. Например (возможно, нуждается в спецификаторах на комбинациях двоичных разрядов для создания их неподписанными или длинными):

#define b0  0x00000001
#define b1  0x00000002
: : :
#define b31 0x80000000

unsigned long x = b2 | b7

3/, Если производительность не очень важна и удобочитаемость, важен, можно просто сделать это во времени выполнения с функцией такой как "x = fromBin ("101011011")";.

4/Как подлое решение, Вы могли записать предварительный препроцессор, который проходит Ваши *.cppme файлы и создает *.cpp путем замены всего "0b101011011" - строки типа с их эквивалентными строками "0x15b"). Я не сделал бы этого слегка, так как существуют все виды хитрых комбинаций синтаксиса, о котором Вам, вероятно, придется волноваться. Но это позволило бы Вам писать свою строку, как Вы хотите, не имея необходимость волноваться о капризах компилятора, и Вы могли ограничить ловкость синтаксиса тщательным кодированием.

Конечно, следующий шаг после этого исправил бы GCC для распознавания "0b" констант, но это может быть излишеством :-)

5
ответ дан 1 December 2019 в 17:55
поделиться

Можно добавить больше шаблонных параметров нетипа для "моделирования" дополнительных битов:

// Utility metafunction used by top_bit<N>.
template <unsigned long long N1, unsigned long long N2>
struct compare {
    enum { value = N1 > N2 ? N1 >> 1 : compare<N1 << 1, N2>::value };
};

// This is hit when N1 grows beyond the size representable
// in an unsigned long long.  It's value is never actually used.
template<unsigned long long N2>
struct compare<0, N2> {
    enum { value = 42 };
};

// Determine the highest 1-bit in an integer.  Returns 0 for N == 0.
template <unsigned long long N>
struct top_bit {
    enum { value = compare<1, N>::value };
};

template <unsigned long long N1, unsigned long long N2 = 0>
struct binary {
    enum {
        value =
            (top_bit<binary<N2>::value>::value << 1) * binary<N1>::value +
            binary<N2>::value
    };
};

template <unsigned long long N1>
struct binary<N1, 0> {
    enum { value = (N1 % 10) + 2 * binary<N1 / 10>::value };
};

template <>
struct binary<0> {
    enum { value = 0 } ;
};

Можно использовать это как прежде, например:

binary<1001101>::value

Но можно также использовать следующие эквивалентные формы:

binary<100,1101>::value
binary<1001,101>::value
binary<100110,1>::value

В основном дополнительный параметр дает Вам еще 20 битов для проигрывания с. Вы могли добавить еще больше параметров при необходимости.

Поскольку значение места второго числа используется, чтобы выяснить, как далеко налево первое число должно быть смещено, второе число должно начаться с 1. (Это требуется так или иначе, начиная с запуска его с 0 заставил бы число интерпретироваться как восьмеричное число.)

3
ответ дан 1 December 2019 в 17:55
поделиться
template<unsigned int p,unsigned int i> struct BinaryDigit 
{
  enum  { value = p*2+i };
  typedef BinaryDigit<value,0> O;
  typedef BinaryDigit<value,1> I;
};
struct Bin
{
  typedef BinaryDigit<0,0> O;
  typedef BinaryDigit<0,1> I;
};

Разрешение:

Bin :: O :: I :: I :: O :: O :: value

намного более подробный, но без ограничений (пока вы не достигнете размера беззнакового int конечно).

3
ответ дан 1 December 2019 в 17:55
поделиться

Технически это не C или C ++, это специфическое расширение GCC, но GCC допускает двоичные константы , как показано здесь :

 The following statements are identical:

 i =       42;
 i =     0x2a;
 i =      052;
 i = 0b101010;

Hope что помогает. Некоторые компиляторы Intel и, я уверен, другие, реализуют некоторые расширения GNU. Может, тебе повезет.

3
ответ дан 1 December 2019 в 17:55
поделиться

A simple #define works very well:

#define HEX__(n) 0x##n##LU

#define B8__(x) ((x&0x0000000FLU)?1:0)\
               +((x&0x000000F0LU)?2:0)\
              +((x&0x00000F00LU)?4:0)\
               +((x&0x0000F000LU)?8:0)\
               +((x&0x000F0000LU)?16:0)\
               +((x&0x00F00000LU)?32:0)\
               +((x&0x0F000000LU)?64:0)\
               +((x&0xF0000000LU)?128:0)

#define B8(d) ((unsigned char)B8__(HEX__(d)))
#define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) + B8(dlsb))
#define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) + ((unsigned long)B8(db2)<<16) + ((unsigned long)B8(db3)<<8) + B8(dlsb))

B8(011100111)
B16(10011011,10011011)
B32(10011011,10011011,10011011,10011011)

Not my invention, I saw it on a forum a long time ago.

2
ответ дан 1 December 2019 в 17:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: