Как собрать несколько символов в число?

Hardwell
Offline
Зарегистрирован: 04.01.2017

Доброго времени суток!

Существует несколько переменных (a, b, c, d). Каждая из этих переменных может хранить в себе либо 1, либо 0.

Мне необходимо собрать значения всех этих переменных в единое число.

Пример:

(a = 1 / b = 0 / c = 0 / d = 1) => 1001

(a = 0 / b = 0 / c = 0 / d = 0) => 0000

Есть идеи?

sadman41
Offline
Зарегистрирован: 19.10.2016

Дайте подумать.... а что если умножать каждое на 10^n и складывать?

bwn
Offline
Зарегистрирован: 25.08.2014

bitSet();

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Hardwell пишет:

Как собрать несколько символов в число?

Существует несколько переменных (a, b, c, d). Каждая из этих переменных может хранить в себе либо 1, либо 0.

Вы бы для начала определились, что у Вас в этих переменных, символы '0' и '1' или числа 0 и 1. А то Вы в показаниях путаетесь.

Если Вы не видите разницы между символами и числами (или не знаете, что у Вас там), то ответ - никак, пока не почитаете умных книжек и не научитесь эту разницу видеть.

Hardwell
Offline
Зарегистрирован: 04.01.2017

a, b, c, d = переменные с целочисленным типом данных (int).

Записывается число 0 или 1. Не true/false. 

В зависимости от значений этих переменных мне необходимо собирать код, состоящий из 4х цифр. (0000 / 1111 /1001 и др.).

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
int a,b,c,d;
int res=(a&1)<<3+(b&1)<<2+(c&1)<<1+(d&1);

 

Hardwell
Offline
Зарегистрирован: 04.01.2017

Выдает 256

int a, b, c, d;
int res;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  delay(1000);
  a = 1;
  b = 0;
  c = 1;
  d = 1;
  res = (a&1)<<3+(b&1)<<2+(c&1)<<1+(d&1);
  Serial.println(res);
}

void loop() {
  // put your main code here, to run repeatedly: 

}

 

Hardwell
Offline
Зарегистрирован: 04.01.2017

sadman41, в сумме код большой, поэтому это слишком загромождает код программы в целом. Нужно более простое решение.

bwn, сейчас прочитаю про эту функцию.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
/**/
int convert(byte a, byte b, byte  c, byte  d) {
  return (((a & 0x1) << 3) | ((b & 0x1) << 2) | ((c & 0x1) << 1) | (d & 0x1));
}
void setup() {
  Serial.begin(9600);
  Serial.println(convert(1, 1, 1, 1));
}
void loop() {
}

 

Hardwell
Offline
Зарегистрирован: 04.01.2017

qwone пишет:

/**/
int convert(byte a, byte b, byte  c, byte  d) {
  return (((a & 0x1) << 3) | ((b & 0x1) << 2) | ((c & 0x1) << 1) | (d & 0x1));
}
void setup() {
  Serial.begin(9600);
  Serial.println(convert(1, 1, 1, 1));
}
void loop() {
}

 

Теперь выводит 15

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
/**/
int convert(byte a, byte b, byte  c, byte  d) {
  return (((a & 0x1) << 3) | ((b & 0x1) << 2) | ((c & 0x1) << 1) | (d & 0x1));
}
void setup() {
  Serial.begin(9600);
  Serial.println(convert(1, 1, 1, 1),BIN);
}
void loop() {
}

 

Efim
Offline
Зарегистрирован: 04.05.2018

В переменную нужно писать с маской 

int a,b,c,d;
int res=((res&0x7)|(a<<3))+((res&0xB)|(b<<2))+((res&0xD)|(c<<1))+((res&0xE)|(d));

 

Efim
Offline
Зарегистрирован: 04.05.2018

Ну или можно просто так, но это опасно. 

    int a=1;
    int b=1;
    int c=1;
    int d=0;
    int res=(a<<3)+(b<<2)+(c<<1)+d;

 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

qwone, Efim, вы предлагате для ТС варианты, которые просто слипляют биты, а ему нужно слипить числа. По моему обычным умножением на 1, на 10, на 100, на 1000  и последующим суммированием -самый простой способ :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Квон, Ефим, Вы чего пишете? Ему же десятичное число 1001 собрать надо, а Вы ему двоичные соибраете.

sadman41 написал нормальное решение. Не понимаю, чем оно не устраивает. Хоттие эффективности, заменяйте умножение на два сдвига (вроде 8+2 по-прежнему 10, Дума же этого не отменила пока).

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Efim, умножение , да не то.  Вот что надо:  a*1 + b*10 +c*100 +d*1000

Efim
Offline
Зарегистрирован: 04.05.2018

Я понял вас. Просто для меня десятичное или двоичное число это всего лишь его представление, а считаю в той системе в которой удобно, ведь результат один)

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Efim, ну где ж один? Результат разный. Причём я не уверен, что это то, что нужно ТС. Ведь числа с нолём впереди он не получит, остаётся только строку собирать.

Efim
Offline
Зарегистрирован: 04.05.2018

Я про то что человеку нужен десятичный ответ, хотя он использует только 1 и 0. Просто для себя вывел бы бинарное значение. А т.к. нужно десятичное то тут вы правы, нужно обычное умножение со сложением.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Прежде всего ТС, надо знать что он хочет, а так же знать основы. А то что я написал это просто "бег на месте" или "бег по кругу". Пользы ему это не принест.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Efim пишет:

Я про то что человеку нужен десятичный ответ, хотя он использует только 1 и 0. Просто для себя вывел бы бинарное значение.

Так Вы ж получаете другое значение! И от системы это никак не зависит - Вы считаете другое число.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Hardwell пишет:

sadman41, в сумме код большой, поэтому это слишком загромождает код программы в целом. 

Шта? Перемножить и сложить 4 числа - большой код?

int a = 1, b = 0, c = 0, d = 1;

int result = 1000*a + 100*b + 10*c + d;

Это большой код? Однако. Правда, нихрена неясно - вам надо четырёхСИМВОЛЬНЫЙ код получить, или число? Потому как, если брать предыдущий пример и все переменные, кроме d, сделать 0 - то на выходе получится ЧИСЛО 1, а не СИМВОЛЬНЫЙ код "0001". Так что вы определитесь, что вам нужно. На всякий - вариант с символьным кодом:

int a=1, b =0, c=0, d=1;

char result[5] = {0};

result[0] = a ? '1' : '0';
result[1] = b ? '1' : '0';
result[2] = c ? '1' : '0';
result[3] = d ? '1' : '0';

Но всё это изврат, и что-то мне подсказывает, что налицо попытка решить задачу не так, как правильно.

yarus
Offline
Зарегистрирован: 17.06.2017
187 0 86 90 17 64 190 1    -   Строка типа String
BB 0 56 5A 11 40 BE 1 
1870869017641901    -   Строка типа String
1870869017641901   -   массив
1870869017641901   -  массив
4294967295
4294967295
 
Вот результат работы моей проги... 1я и 3я строки имеют тип String и содержат числа.
Вопрос: как из этих строк получить числа (например, типа Unsigned Long int)?
Все способы, что я пробовал, выдают мне 6ю и 7ю строки, а мне надо, чтобы цифры результирующих строк совпадали с исходными...
Как это выполнить???
ПС... ПРавда, 2я строка тоже типа "стринг", только в 16-чном коде...
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну а мозг то зачем было выносить? На Вашу третью строку напустите s.parseInt(), а из первой удалите пробелы и тоже самое.

yarus
Offline
Зарегистрирован: 17.06.2017

Весь "скипитр" в том, что

1) я раньше не сталкивался с подобной необходимостью

2) Как я полнял, сей метод для СЕРИАЛ порта, а у меня обычная текстовая переменная, содержащая цифры

Вот из нее-то и надо получить число, цифры в котором совпадали бы с исходными...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

yarus пишет:

2) Как я полнял, сей метод для СЕРИАЛ порта, 

Ну, у класса String он же называется toInt - документация читать пробовали?

yarus
Offline
Зарегистрирован: 17.06.2017

Не только читать, но и использовать, однако, цифры результата не совпадют с исходными...

b707
Offline
Зарегистрирован: 26.05.2017

yarus пишет:

1870869017641901   -   массив
 
4294967295
4294967295
 
 
Вопрос: как из этих строк получить числа (например, типа Unsigned Long int)?
Все способы, что я пробовал, выдают мне 6ю и 7ю строки, а мне надо, чтобы цифры результирующих строк совпадали с исходными..

никак вы не выполните. Ваши числа слишком длинные. Результат, который вы получаете - 4294967295 - есть максимальное число, которое может хранится в типе Unsigned Long int.

Для того, что преобразовать вашу строку в число - вам придется либо использовать нестандартные для ардуино типы, например uint64_t, либо - что более правильно - разбить строку на части и преобразовывать в 2 числа

yarus
Offline
Зарегистрирован: 17.06.2017

Спасибо за подсказку. попробую разбиение...

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

А что тип unsigned long long запретили?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

qwone пишет:

А что тип unsigned long long запретили?

Так b707 про него и писал, только назвал его uint64_t.

Просто toInt(), который я посоветовал, с ним не работает.

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Говорят, что запретили - в нем классов не было...

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

sadman41 пишет:

Говорят, что запретили - в нем классов не было...

А я слышал, что классы вроде были, но некошерные - не от Квона.