скопировано из документа pytorch :
a = torch.ones(5)
print(a)
тензор ([1., 1., 1., 1., 1.])
blockquote>b = a.numpy() print(b)
[1. 1. 1. 1. 1.]
blockquote>
Я использовал бы немного оператор сдвига:
const int has_nukes = 1<<0;
const int has_bio_weapons = 1<<1;
const int has_chem_weapons = 1<<2;
// ...
int dangerous_mask = has_nukes | has_bio_weapons | has_chem_weapons;
bool is_dangerous = (country->flags & dangerous_mask) == dangerous_mask;
Это еще лучше, чем лавинная рассылка 0.
Как в стороне:
Особенно, если Вы имеете дело с большим набором, вместо того, чтобы пройти [незначительное] умственное усилие по записи последовательности объемов сдвига, можно заставить каждую константу зависеть от ранее определенной константы:
const int has_nukes = 1;
const int has_bio_weapons = has_nukes << 1;
const int has_chem_weapons = has_bio_weapons << 1;
const int has_nunchuks = has_chem_weapons << 1;
// ...
немного избыточные Взгляды, но это является менее склонным к опечатке. Кроме того, можно просто вставить новую константу в середине, не имея необходимость касаться любой другой строки кроме той сразу после него:
const int has_nukes = 1;
const int has_gravity_gun = has_nukes << 1; // added
const int has_bio_weapons = has_gravity_gun << 1; // changed
const int has_chem_weapons = has_bio_weapons << 1; // unaffected from here on
const int has_nunchuks = has_chem_weapons << 1;
// ...
Выдерживают сравнение с:
const int has_nukes = 1 << 0;
const int has_bio_weapons = 1 << 1;
const int has_chem_weapons = 1 << 2;
const int has_nunchuks = 1 << 3;
// ...
const int has_scimatar = 1 << 28;
const int has_rapier = 1 << 28; // good luck spotting this typo!
const int has_katana = 1 << 30;
И:
const int has_nukes = 1 << 0;
const int has_gravity_gun = 1 << 1; // added
const int has_bio_weapons = 1 << 2; // changed
const int has_chem_weapons = 1 << 3; // changed
const int has_nunchuks = 1 << 4; // changed
// ... // changed all the way
const int has_scimatar = 1 << 29; // changed *sigh*
const int has_rapier = 1 << 30; // changed *sigh*
const int has_katana = 1 << 31; // changed *sigh*
Как в стороне к моему в стороне, вероятно, одинаково трудно определить опечатку как это:
const int has_nukes = 1;
const int has_gravity_gun = has_nukes << 1;
const int has_bio_weapons = has_gravity_gun << 1;
const int has_chem_weapons = has_gravity_gun << 1; // oops!
const int has_nunchuks = has_chem_weapons << 1;
Так, я думаю, что основное преимущество этого каскадного синтаксиса при контакте со вставками и удалениями констант.
Нет никакого синтаксиса для литеральных двоичных констант в C++ пути, там для шестнадцатеричного и восьмеричного. Самая близкая вещь для того, что похоже, что Вы пытаетесь сделать, состояла бы в том, чтобы, вероятно, изучить и использовать bitset.
Java не поддерживает двоичные литералы также, к сожалению. Однако это имеет перечисления , который может использоваться с EnumSet
. EnumSet
представляет перечислимые значения внутренне с битовыми полями и представляет Set
интерфейс для управления этими флагами.
, С другой стороны, Вы могли использовать разрядные смещения (в десятичном числе) при определении значений:
const int HAS_NUKES = 0x1 << 0;
const int HAS_BIO_WEAPONS = 0x1 << 1;
const int HAS_CHEM_WEAPONS = 0x1 << 2;
Я пишу двоичные литералы как это:
const int has_nukes = 0x0001;
const int has_bio_weapons = 0x0002;
const int has_chem_weapons = 0x0004;
Это более компактно, чем Ваша предложенная нотация и легче читать. Например:
const int upper_bit = 0b0001000000000000000;
по сравнению с:
const int upper_bit = 0x04000;
Вы заметили, что версия двоичных файлов не была даже несколькими 4 битами? Вы думали, что это был 0x10000?
С маленьким шестнадцатеричным числом практики или восьмеричный легче для человека, чем двоичный файл. И, по-моему, легче считать то использование операторы сдвига. Но я признаю, что мои годы работы ассемблера могут сместить меня на той точке.
Термин, который Вы хотите, двоичные литералы
, Ruby имеет их с синтаксисом, который Вы даете.
Одна альтернатива должна определить макросы помощника для преобразования для Вас. Я нашел следующий код в http://bytes.com/groups/c/219656-literal-binary
/* Binary constant generator macro
* By Tom Torfs - donated to the public domain
*/
/* All macro's evaluate to compile-time constants */
/* *** helper macros *** */
/* turn a numeric literal into a hex constant
* (avoids problems with leading zeroes)
* 8-bit constants max value 0x11111111, always fits in unsigned long
*/
#define HEX_(n) 0x##n##LU
/* 8-bit conversion function */
#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)
/* *** user macros *** /
/* for upto 8-bit binary constants */
#define B8(d) ((unsigned char) B8_(HEX_(d)))
/* for upto 16-bit binary constants, MSB first */
#define B16(dmsb, dlsb) (((unsigned short) B8(dmsb) << 8) \
| B8(dlsb))
/* for upto 32-bit binary constants, MSB first */
#define B32(dmsb, db2, db3, dlsb) (((unsigned long) B8(dmsb) << 24) \
| ((unsigned long) B8( db2) << 16) \
| ((unsigned long) B8( db3) << 8) \
| B8(dlsb))
/* Sample usage:
* B8(01010101) = 85
* B16(10101010,01010101) = 43605
* B32(10000000,11111111,10101010,01010101) = 2164238933
*/
<забастовка> Это обсуждение может быть интересна забастовка>... Возможно, был, поскольку ссылка является битой, к сожалению. Это описало основанный на шаблоне подход, подобный другим ответам здесь.
И также существует вещь, названная BOOST_BINARY.
GCC поддерживает двоичные константы как расширение с тех пор 4.3. Посмотрите объявление (посмотрите на раздел "New Languages and Language specific improvements").
Можно использовать < < если Вам нравится.
int hasNukes = 1;
int hasBioWeapons = 1 << 1;
int hasChemWeapons = 1 << 2;
Библиотека Стандарта C++ является Вашим другом:
#include <bitset>
const std::bitset <32> has_nukes( "00000000000000000000000000000001" );
Между прочим, следующая версия C++ будет поддерживать определяемые пользователем литералы. Они уже включены в рабочий проект. Это позволяет такой материал (давайте надеяться, что у меня нет слишком многих ошибок в нем):
template<char... digits>
constexpr int operator "" _b() {
return conv2bin<digits...>::value;
}
int main() {
int const v = 110110110_b;
}
conv2bin
был бы шаблон как это:
template<char... digits>
struct conv2bin;
template<char high, char... digits>
struct conv2bin<high, digits...> {
static_assert(high == '0' || high == '1', "no bin num!");
static int const value = (high - '0') * (1 << sizeof...(digits)) +
conv2bin<digits...>::value;
};
template<char high>
struct conv2bin<high> {
static_assert(high == '0' || high == '1', "no bin num!");
static int const value = (high - '0');
};
ну, что мы получаем, двоичные литералы, которые уже оценивают полностью во время компиляции из-за "constexpr" выше. Вышеупомянутое использование трудно кодированный интервал возвращает тип. Я думаю, что можно было даже заставить его зависеть от длины двоичной строки. Это использует следующие функции для любого заинтересованного:
На самом деле, текущая соединительная линия GCC реализации variadic шаблоны и статические утверждения. Давайте надеяться, что это будет скоро поддерживать другие два. Я думаю, что C++ 1x будет качать дом.
Один, немного ужасный способ, которым Вы могли сделать это, путем генерации.h файла с большим количеством #defines...
#define b00000000 0
#define b00000001 1
#define b00000010 2
#define b00000011 3
#define b00000100 4
и т.д. Это могло бы иметь смысл для 8-разрядных чисел, но вероятно не для 16-разрядного или большего.
, С другой стороны, делают это (подобный ответу Zach Scrivena):
#define bit(x) (1<<x)
int HAS_NUKES = bit(HAS_NUKES_OFFSET);
int HAS_BIO_WEAPONS = bit(HAS_BIO_WEAPONS_OFFSET);
Следующая версия C++, C++ 0x, представит определяемые пользователем литералы. Я не уверен, будут ли двоичные числа частью стандарта, но в худшем Вы сможете включить его сами:
int operator "" _B(int i);
assert( 1010_B == 10);