Преобразование в строку
От: YourLastSong  
Дата: 24.12.11 17:33
Оценка:
Здравствуйте, уважаемые господа.

Задача такая:

мне необходимо объединить два числа, содержащие только 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, пропадут из конечного числа. Как этого лучше всего избежать?

И каким образом после этого можно получить два числа из одного?

Заранее благодарю за возможные ответы.
Re: Преобразование в строку
От: kpcb Россия  
Дата: 24.12.11 18:36
Оценка:
Здравствуйте, 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;
}
Re[2]: Преобразование в строку
От: YourLastSong  
Дата: 24.12.11 19:59
Оценка:
K>Если вопрос в том, как вернуть в начало пропавшие нули, то это можно сделать так:

Вы не совсем прав. меня поняли.

Смотрите, у меня есть два числа.

Например, 4 и 10.

Их можно представить в виде 0100 и 1010, после чего объединить в одно число, являющееся как бы битовой маской (в данном случае это будет 01001010). Потом разбить их обратно на два, тем самым экономя место на сохранение их в файл (вместо 8 байт будем хранить всего 4 байта). Разумеется, экономя всего 4 байта, мы мало чего с этого полезного получим, однако если таких чисел довольно много, то такой подход уже довольно полезен.

Да, я знаю про bitset, boost::dynamic_bitset и т.д., однако даже при их использовании я получу гораздо меньше пользы в данном случае.
Re: Преобразование в строку
От: vladimir_i СССР  
Дата: 24.12.11 22:31
Оценка: -2
Здравствуйте, YourLastSong, Вы писали:

YLS>Здравствуйте, уважаемые господа.


YLS>Задача такая:


YLS>мне необходимо объединить два числа, содержащие только 0 и 1 (по 5 цифр в каждом), в одно, а через некоторое время разбить получившееся число снова на два разных.


YLS>Начальные числа (те, что содержат только 0 и 1), разумеется, всегда разные — зависит это от условий.


YLS>Лучше всего для этого способа подошёл бы такой подход:



YLS>
YLS>std::string str;
YLS>unsigned long value;

YLS>if (condition)
YLS>{
YLS>str += "00000";
YLS>}
YLS>else if (condition_new)
YLS>{
YLS>str += "00001";
YLS>}
YLS>...

YLS>if (str.size () == 10)
YLS>{
YLS>std::istringstream iss;
YLS>iss >> value;
YLS>}
YLS>



YLS>Однако в таком случае все 0, до первой 1, пропадут из конечного числа. Как этого лучше всего избежать?


YLS>И каким образом после этого можно получить два числа из одного?


YLS>Заранее благодарю за возможные ответы.



Примерно, как-то так:
str.resize(10);
sprintf((char*)str.c_str(),"%.05d%.05d",nValue/100000,nValue%100000);
Re[2]: 2 uzhas
От: vladimir_i СССР  
Дата: 25.12.11 13:03
Оценка: -1
Здравствуйте, uzhas, Вы поставили -1.

Очевидно, вы знаете правильный ответ на поставленный вопрос.
Не томите, сделайте топикстартеру приятное.
Re: Преобразование в строку
От: zakharov75 Великобритания  
Дата: 25.12.11 13:41
Оценка: 1 (1)
Здравствуйте, YourLastSong, Вы писали:

YLS>Здравствуйте, уважаемые господа.


YLS>Задача такая:


YLS>мне необходимо объединить два числа, содержащие только 0 и 1 (по 5 цифр в каждом), в одно, а через некоторое время разбить получившееся число снова на два разных.


YLS>Начальные числа (те, что содержат только 0 и 1), разумеется, всегда разные — зависит это от условий.


YLS>Лучше всего для этого способа подошёл бы такой подход:



YLS>
YLS>std::string str;
YLS>unsigned long value;

YLS>if (condition)
YLS>{
YLS>str += "00000";
YLS>}
YLS>else if (condition_new)
YLS>{
YLS>str += "00001";
YLS>}
YLS>...

YLS>if (str.size () == 10)
YLS>{
YLS>std::istringstream iss;
YLS>iss >> value;
YLS>}
YLS>



YLS>Однако в таком случае все 0, до первой 1, пропадут из конечного числа. Как этого лучше всего избежать?


YLS>И каким образом после этого можно получить два числа из одного?


YLS>Заранее благодарю за возможные ответы.



//допустим имеем для начала
numb1=4; //00100
numb2=10; //01010
unsigned 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.

Если нужно преобразовать в строку бинарного вида, то это немного хотрее.
Я вот нагуглил за вару минут:



#define BYTETOBINARYPATTERN "%d%d%d%d%d%d%d%d"
#define BYTETOBINARY(byte)  \
  (byte & 0x80 ? 1 : 0), \
  (byte & 0x40 ? 1 : 0), \
  (byte & 0x20 ? 1 : 0), \
  (byte & 0x10 ? 1 : 0), \
  (byte & 0x08 ? 1 : 0), \
  (byte & 0x04 ? 1 : 0), \
  (byte & 0x02 ? 1 : 0), \
  (byte & 0x01 ? 1 : 0) 

printf("M: "BYTETOBINARYPATTERN" "BYTETOBINARYPATTERN"\n",
  BYTETOBINARY(M>>8), BYTETOBINARY(M));


За опечатки извините, компилятора под рукой, потому не проверял.
Re[2]: Преобразование в строку
От: wander  
Дата: 25.12.11 21:47
Оценка:
Здравствуйте, vladimir_i, Вы писали:

_>Примерно, как-то так:

_>
_>str.resize(10);
_>sprintf((char*)str.c_str(),"%.05d%.05d",nValue/100000,nValue%100000);
_>


Очевидно минус тебе поставили за хак со снятием константности.
Re[3]: Преобразование в строку
От: chemey  
Дата: 26.12.11 09:05
Оценка:
Здравствуйте, YourLastSong, Вы писали:

YLS>Смотрите, у меня есть два числа.

YLS>Например, 4 и 10.

YLS>Их можно представить в виде 0100 и 1010, после чего объединить в одно число, являющееся как бы битовой маской (в данном случае это будет 01001010). Потом разбить их обратно на два, тем самым экономя место на сохранение их в файл (вместо 8 байт будем хранить всего 4 байта). Разумеется, экономя всего 4 байта, мы мало чего с этого полезного получим, однако если таких чисел довольно много, то такой подход уже довольно полезен.


А если эти два числа записать в строку в таком виде:
4 10

Или даже в таком виде (16-разрядные числа):
4 A

То экономия будет вообще офигенно налицо, никаких проблем с разделением двух чисел не будет, и вообще настанет рай на облацех.

Я не понимаю необходимости записывать числа в файл в виде строки символов именно единицы и нуля. Как именно сформулирована задача?
Бзззззззжжжжж
Re[3]: LOL
От: vladimir_i СССР  
Дата: 26.12.11 16:28
Оценка:
Здравствуйте, wander, Вы писали:

W>Здравствуйте, vladimir_i, Вы писали:


_>>Примерно, как-то так:

_>>
_>>str.resize(10);
_>>sprintf((char*)str.c_str(),"%.05d%.05d",nValue/100000,nValue%100000);
_>>


W>Очевидно минус тебе поставили за хак со снятием константности.

Главным, в том что я написал является форматированный вывод в некоторый буфер с нужным количеством нулей.

Так:
sprintf(<buffer>,"%.010d",value);


или (автор просил разбить на два числа по 5 символов) так:

sprintf(<buffer1>,"%.05d",value/100000);
sprintf(<buffer2>,"%.05d",value%100000);


Придираться к "хакам", очевидно, не имеющим отношения к вопросу как-то странно

P.S.

На основании примера с числами "00000" и "00001" я заключил, что речь о представлении чисел именно в 10-ной системе, а не в 2-ой.
Ибо у битсетов нет проблем с невыводом нулей:

std::cout<<std::bitset<5>(value&0xf);
std::cout<<std::bitset<5>((value>>5)&0xf);
Re[3]: Преобразование в строку
От: VladFein США  
Дата: 27.12.11 22:21
Оценка:
Здравствуйте, YourLastSong, Вы писали:

YLS>Смотрите, у меня есть два числа.

YLS>Например, 4 и 10.
YLS>Их можно представить в виде 0100 и 1010, после чего объединить в одно число, являющееся как бы битовой маской (в данном случае это будет 01001010). Потом разбить их обратно на два, тем самым экономя место на сохранение их в файл (вместо 8 байт будем хранить всего 4 байта).

Не совсем понятна Ваша арифметика.
Какие 8 байт, 4 байта?
У Вас есть два пятибитовых числа, которые займут или одно двухбайтовое место, или два однобайтовых.
Вы можете легко упаковать (без компрессии) восемь таких чисел в пять байтов.
Re[3]: Преобразование в строку
От: RLX  
Дата: 28.12.11 04:55
Оценка:
Здравствуйте, YourLastSong, Вы писали:

K>>Если вопрос в том, как вернуть в начало пропавшие нули, то это можно сделать так:


YLS>Вы не совсем прав. меня поняли.


YLS>Смотрите, у меня есть два числа.


YLS>Например, 4 и 10.


YLS>Их можно представить в виде 0100 и 1010, после чего объединить в одно число, являющееся как бы битовой маской (в данном случае это будет 01001010). Потом разбить их обратно на два, тем самым экономя место на сохранение их в файл (вместо 8 байт будем хранить всего 4 байта). Разумеется, экономя всего 4 байта, мы мало чего с этого полезного получим, однако если таких чисел довольно много, то такой подход уже довольно полезен.


YLS>Да, я знаю про bitset, boost::dynamic_bitset и т.д., однако даже при их использовании я получу гораздо меньше пользы в данном случае.


Может это нужно

int A = 4;
int B = 10;

int C = ( A << 16 ) | B;

int eA = C >> 16;
int eB = C & 0xFFFF;
Re[4]: LOL
От: chemey  
Дата: 28.12.11 11:17
Оценка:
Здравствуйте, 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.


То, что ты так, возможно, привык и у тебя всегда все работает, не является оправданием.
Бзззззззжжжжж
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.