
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.75] |
![]() |
|
Страницы: (2) 1 [2] все ( Перейти к последнему сообщению ) |
![]() |
Сообщ.
#16
,
|
|
Majestio, ты что-то путаешь. У std::bitset<> нет конструктора, принимающего массив байт. Его конструкторы, принимающие строки в том или ином виде, как обозначение бита рассматривают каждый символ, а не бит. Т.е. можно получить std::bitset<8>("00110110").to_ulong() == 0b110110ul (или std::bitset<8>(0b110110ul).to_string() == "00110110"), но не или std::bitset<8>("01").to_ulong() == 0b00000001ul
|
Сообщ.
#17
,
|
|
|
Qraizer, да - всё верно! Перепутал я малёха. Свой пример с std::bitset я исправил.
|
Сообщ.
#18
,
|
|
|
tumanovalex, кстати, я тоже когда-то делал для себя заготовки для работы с битами без STL - ознакомься
![]() |
![]() |
Сообщ.
#19
,
|
|
В общем, если кому интересно, то универсальный код преобразования обоих типов ...э-э-э, типов в битовый вид.
![]() ![]() #include <limits> #include <concepts> #include <cmath> #include <bit> /* преобразование целых в строку */ std::string TypeToBin(std::integral auto source) { int const size = std::numeric_limits<unsigned char>::digits * sizeof(source); // размер в битах std::string str(size, ' '); for (int i = size - 1; i >= 0; i--) { str[i] = (source & 1) + '0'; source >>= 1; } return str; } /* преобразование вещественных в строку (для не IEEE-совместимых не тестировалось) */ std::string TypeToBin(std::floating_point auto source) { std::string buf; int power; // порядок source const auto &properties = std::numeric_limits<decltype(source)>{}; const unsigned shiftedPower = static_cast<unsigned>(properties.max_exponent - properties.min_exponent); buf.reserve(properties.digits + std::bit_width(shiftedPower) + 3); // + точка, 'b' и знак buf = std::signbit(source) + '0'; // первым знак if (!std::isfinite(source)) // проверка на спец.форматы NaN и inf { // сначала избавиться от порядка, но сохранить мантиссу (на случай NaN особенно) // используем бесконечность как образец в памяти ... decltype(source) pattern = properties.infinity(); const char (&nanByte)[sizeof(pattern)] = reinterpret_cast<const char (&)[sizeof(pattern)]>(pattern); char (&srcByte)[sizeof(source)] = reinterpret_cast< char (&)[sizeof(source)]> (source); // ... и обрабатываем source побайтно, стирая порядок ... for (int i = 0; i < sizeof(nanByte); ++i) srcByte[i] ^= nanByte[i]; // ... а затем заменяем его на несмещённый порядок 0 // это также учтёт явный старший бит, если он есть, т.к. XOR применяется дважды // + нам пофик на endianess, т.к. он одинаковый для source и pattern pattern = 1; for (int i = 0; i < sizeof(nanByte); ++i) srcByte[i] ^= nanByte[i]; source = abs(source); // теперь можно вычислять модуль, в source не спец.формат // максимальный порядок спец.форматов с учётом его разрядности в типе source, т.к. реализации // любят в FP_ILOGBNAN совать просто MAX_INT power = FP_ILOGBNAN & (std::bit_ceil(shiftedPower) - 1); } else // для остальных форматов всё значительно проще { source = abs(source); // модуль можно сразу power = logb(source); // порядок source= ldexp(source, -power); // чистая мантисса (с порядком 0) // использовать frexp() нежелательно, т.к. она возвращает мантиссу, сдвинутую в [0.5, 1) // что уменьшает точность на бит и требует специальной дополнительной обработки её и порядка, // особенно рядом с std::numeric_limits<>::denorm_min() } /* обработать мантиссу */ for (int i = 0; i < properties.digits; ++i) { buf += static_cast<char>(static_cast<int>(source)); source -= buf.back(); buf.back()+= '0'; source *= static_cast<decltype(source)>(2); } buf.insert(2, 1, '.'); // добавить точку в buf // обработать порядок buf += 'b'; // power хранит меньшую разрядность, чем способен его тип, например 12 для IEEEшного double, // поэтому имеет смысл отрезать от него только нужное количество младших бит buf += TypeToBin(power).substr(std::numeric_limits<decltype(power)>::digits - 1 // знак уже учтён - std::bit_width(shiftedPower / 2)); // а порядок смещён return buf; } |