Нужно перевести число из Little endian в big-endian.. Дано изначально 32 битное число представленное в десятичном виде.. Нужно выдать конечное число, тоже в 10 виде.. Допустим 3496683923 в 16 системе будет выглядеть как D06B2993.. Делим по байтам: D0 6B 29 93.. Меняем местами относительно концов.. 93 29 6B D0. Собираем обратно все это дело 93296BD0 и переводим в 10 вид: 2468965328.
Если есть способ по проще, то можете пожалуйста объяснить? Есть набросок кода, который преобразует в 16 систему.. Но как от туда забрать эти данные и преобразовать в 10 сс, понятия не имею. (код не мой, не придирайтесь сильно)
#include <iostream>
#include <sstream>
#include <string.h>
using namespace std;
int main()
{
string normal;
int const Value = 3496683923;
unsigned char const *pByte = (unsigned char const *)&Value;
for (size_t i = 0; i < sizeof (Value); ++i)
{
cout << hex<< static_cast<int>(pByte[i]) << endl;
}
cout << endl;
return 0;
}
Методов много - функция ntohl
, инструкция ассемблера bswap
, упаковка байтов в новом порядке через кастинг к байтовому массиву...
Если оттолкнуться от Вашего цикла и использовать битовые операции:
Выделяем младший байт источника, копируем в младший байт приёмника.
Сдвигаем источник вправо (теперь второй байт станет младшим),
а приёмник влево (теперь младший байт станет вторым).
Продолжаем, пока исходно младший байт не встанет на старшее место.
int main()
{
unsigned int Value = 3496683923;
unsigned int res = 0;
std::cout << Value << " " << std::hex << Value << std::endl;
for (size_t i = 0; i < sizeof(Value); ++i)
{
res = (res << 8) | (Value & 0xFF);
Value >>= 8;
}
std::cout << std::dec << res << " " << std::hex << res;
}
3496683923 d06b2993
2468965328 93296bd0
Вариант внутренности цикла, не требующий отказа от const
{
res = (res << 8) | ((Value >> 8 * i) & 0xFF);
}
Например, можно воспользоваться такой функцией:
unsigned int
bswap (unsigned int v)
{
return (v >> 24) | ((v >> 8) & 0xff00)
| ((v << 8) & 0xff0000) | (v << 24);
}
Обратите внимание, что тип аргумента -- unsigned.
Впрочем, если вы настаиваете на типе int, как для аргумента, так и для результата, то достаточно привести к unsigned только в одном месте --
return ((unsigned)v >> 24) | ....
Преобразование между little-endian и big-endian предполагает, по определению, смену порядка следования байтов на обратный. Никакого отношения ни к каким "системам счисления" эта тема не имеет вообще.
Сделать это можно массой разнообразных способов... Например, в терминах языка С
uint32_t little_endian = 3496683923;
union { uint32_t v; uint8_t b[4]; } u = { little_endian };
uint8_t t = u.b[0]; u.b[0] = u.b[3]; u.b[3] = t;
t = u.b[1]; u.b[1] = u.b[2]; u.b[2] = t;
uint32_t big_endian = u.v;
printf("%" PRIu32 "\n", big_endian);
Можно использовать boost.endian:
#include <boost/endian/conversion.hpp>
#include <iostream>
#include <cstdint>
int main()
{
::std::int32_t value{};
::std::cin >> value;
::boost::endian::endian_reverse_inplace(value);
::std::cout << value << ::std::endl;
return 0;
}
online compiler
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Подскажите чайнику,пожалуйста, как обойти ситуациюВ своем приложении решил создать иерархическую структуру данных
Нужна помощь умных людейНужно: Создать класс СТРОКА, реализующий текстовую строку
Через std::setfill('0') задаём заполнитель, через std::setw(N) задаём ширину выводимого числаВсё что не занято самим числом будет заполнено символом-заполнителем