мне необходимо объединить два числа, содержащие только 0 и 1 (по 5 цифр в каждом), в одно, а через некоторое время разбить получившееся число снова на два разных.
Начальные числа (те, что содержат только 0 и 1), разумеется, всегда разные — зависит это от условий.
Лучше всего для этого способа подошёл бы такой подход:
std::string str;
unsigned long value;
if (condition)
{
str += "00000";
}
else if (condition_new)
{
str += "00001";
}
...
if (str.size () == 10)
{
std::istringstream iss;
iss >> value;
}
Однако в таком случае все 0, до первой 1, пропадут из конечного числа. Как этого лучше всего избежать?
И каким образом после этого можно получить два числа из одного?
Здравствуйте, YourLastSong, Вы писали:
YLS>Здравствуйте, уважаемые господа.
YLS>Задача такая:
YLS>мне необходимо объединить два числа, содержащие только 0 и 1 (по 5 цифр в каждом), в одно, а через некоторое время разбить получившееся число снова на два разных.
YLS>Начальные числа (те, что содержат только 0 и 1), разумеется, всегда разные — зависит это от условий.
Если вопрос в том, как вернуть в начало пропавшие нули, то это можно сделать так:
#include <iostream>
#include <iomanip>
#include <ios>
int main(int argc, char *argv[])
{
int value = 101;
std::cout.width(10);
std::cout << std::setfill('0') << std::right << value << std::endl;
return 0;
}
K>Если вопрос в том, как вернуть в начало пропавшие нули, то это можно сделать так:
Вы не совсем прав. меня поняли.
Смотрите, у меня есть два числа.
Например, 4 и 10.
Их можно представить в виде 0100 и 1010, после чего объединить в одно число, являющееся как бы битовой маской (в данном случае это будет 01001010). Потом разбить их обратно на два, тем самым экономя место на сохранение их в файл (вместо 8 байт будем хранить всего 4 байта). Разумеется, экономя всего 4 байта, мы мало чего с этого полезного получим, однако если таких чисел довольно много, то такой подход уже довольно полезен.
Да, я знаю про bitset, boost::dynamic_bitset и т.д., однако даже при их использовании я получу гораздо меньше пользы в данном случае.
Здравствуйте, YourLastSong, Вы писали:
YLS>Здравствуйте, уважаемые господа.
YLS>Задача такая:
YLS>мне необходимо объединить два числа, содержащие только 0 и 1 (по 5 цифр в каждом), в одно, а через некоторое время разбить получившееся число снова на два разных.
YLS>Начальные числа (те, что содержат только 0 и 1), разумеется, всегда разные — зависит это от условий.
YLS>Лучше всего для этого способа подошёл бы такой подход:
YLS>Однако в таком случае все 0, до первой 1, пропадут из конечного числа. Как этого лучше всего избежать?
YLS>И каким образом после этого можно получить два числа из одного?
YLS>Заранее благодарю за возможные ответы.
Здравствуйте, YourLastSong, Вы писали:
YLS>Здравствуйте, уважаемые господа.
YLS>Задача такая:
YLS>мне необходимо объединить два числа, содержащие только 0 и 1 (по 5 цифр в каждом), в одно, а через некоторое время разбить получившееся число снова на два разных.
YLS>Начальные числа (те, что содержат только 0 и 1), разумеется, всегда разные — зависит это от условий.
YLS>Лучше всего для этого способа подошёл бы такой подход:
YLS>Однако в таком случае все 0, до первой 1, пропадут из конечного числа. Как этого лучше всего избежать?
YLS>И каким образом после этого можно получить два числа из одного?
YLS>Заранее благодарю за возможные ответы.
//допустим имеем для начала
numb1=4; //00100
numb2=10; //01010unsigned long value = 0;
//теперь
value |= numb1;
value << 5; // //здесь value=0010000000 или 128
value |= numb2; //здесь value=0010001010 или 138
Если нужно получить обратно два числа, тогда так
допустим имеем для начала
unsigned long value = 138; //здесь value=0010001010
numb1=0;
numb2=0;
numb1=(value&0x3E0)>>5; //здесь numb1=4 или 00100
numb2=value&0x1F; //здесь numb2=10 или 01010
Поэтому для хранения каждого числа нужно всего 2 байта, потому, что 2 в 10 — это меньше двух байт(2 в 16).
Это если в бинарном формате. Ести в текстовом, то 3 байта, т.к. максимальное число будет 3FF.
Если нужно преобразовать в строку бинарного вида, то это немного хотрее.
Я вот нагуглил за вару минут:
Здравствуйте, YourLastSong, Вы писали:
YLS>Смотрите, у меня есть два числа. YLS>Например, 4 и 10.
YLS>Их можно представить в виде 0100 и 1010, после чего объединить в одно число, являющееся как бы битовой маской (в данном случае это будет 01001010). Потом разбить их обратно на два, тем самым экономя место на сохранение их в файл (вместо 8 байт будем хранить всего 4 байта). Разумеется, экономя всего 4 байта, мы мало чего с этого полезного получим, однако если таких чисел довольно много, то такой подход уже довольно полезен.
А если эти два числа записать в строку в таком виде:
4 10
Или даже в таком виде (16-разрядные числа):
4 A
То экономия будет вообще офигенно налицо, никаких проблем с разделением двух чисел не будет, и вообще настанет рай на облацех.
Я не понимаю необходимости записывать числа в файл в виде строки символов именно единицы и нуля. Как именно сформулирована задача?
W>Очевидно минус тебе поставили за хак со снятием константности.
Главным, в том что я написал является форматированный вывод в некоторый буфер с нужным количеством нулей.
Так:
sprintf(<buffer>,"%.010d",value);
или (автор просил разбить на два числа по 5 символов) так:
Придираться к "хакам", очевидно, не имеющим отношения к вопросу как-то странно
P.S.
На основании примера с числами "00000" и "00001" я заключил, что речь о представлении чисел именно в 10-ной системе, а не в 2-ой.
Ибо у битсетов нет проблем с невыводом нулей:
Здравствуйте, YourLastSong, Вы писали:
YLS>Смотрите, у меня есть два числа. YLS>Например, 4 и 10. YLS>Их можно представить в виде 0100 и 1010, после чего объединить в одно число, являющееся как бы битовой маской (в данном случае это будет 01001010). Потом разбить их обратно на два, тем самым экономя место на сохранение их в файл (вместо 8 байт будем хранить всего 4 байта).
Не совсем понятна Ваша арифметика.
Какие 8 байт, 4 байта?
У Вас есть два пятибитовых числа, которые займут или одно двухбайтовое место, или два однобайтовых.
Вы можете легко упаковать (без компрессии) восемь таких чисел в пять байтов.
Здравствуйте, YourLastSong, Вы писали:
K>>Если вопрос в том, как вернуть в начало пропавшие нули, то это можно сделать так:
YLS>Вы не совсем прав. меня поняли.
YLS>Смотрите, у меня есть два числа.
YLS>Например, 4 и 10.
YLS>Их можно представить в виде 0100 и 1010, после чего объединить в одно число, являющееся как бы битовой маской (в данном случае это будет 01001010). Потом разбить их обратно на два, тем самым экономя место на сохранение их в файл (вместо 8 байт будем хранить всего 4 байта). Разумеется, экономя всего 4 байта, мы мало чего с этого полезного получим, однако если таких чисел довольно много, то такой подход уже довольно полезен.
YLS>Да, я знаю про bitset, boost::dynamic_bitset и т.д., однако даже при их использовании я получу гораздо меньше пользы в данном случае.
Здравствуйте, vladimir_i, Вы писали:
_>Главным, в том что я написал является форматированный вывод в некоторый буфер с нужным количеством нулей.
_>Так: _>
_>sprintf(<buffer>,"%.010d",value);
_>
Функция sprintf() является тяжелым наследием, оставшимся от С.
В новом коде ее не рекомендуется применять, т.к. она банально плохо сочетается с С++ (применение тобой хака для скрещивания sprintf() со строками — тому иллюстрация).
_>Придираться к "хакам", очевидно, не имеющим отношения к вопросу как-то странно
В данном случае — не странно. И "хак" я бы не брал в кавычки, потому как у тебя не просто сомнительный код — у тебя код, напрямую нарушающий требования стандарта C++: 21.3.6 basic_string string operations [lib.string.ops]
const charT* c_str() const;
1 Returns: A pointer to the initial element of an array of length size() + 1 whose first size() elements
equal the corresponding elements of the string controlled by *this and whose last element is a
null character specified by charT().
2 Requires: The program shall not alter any of the values stored in the array. Nor shall the program treat the
returned value as a valid pointer value after any subsequent call to a non-const member function of the
class basic_string that designates the same object as this.
То, что ты так, возможно, привык и у тебя всегда все работает, не является оправданием.