
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.154] |
![]() |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
![]() |
|
|
Здравствуйте!
На киберфоруме была предложена функция перевода в двоичное представление на чистом C: ![]() ![]() #include <stdio.h> #include <stdlib.h> #include <stdint.h> char* void2bin(void* data, size_t size) { char* dest = (char*)malloc(1 + 8 * size); char* ptr = dest; uint8_t* b = (uint8_t*)(data)+size - 1; for (size_t bit = 8 * size; bit--; ptr++) { *ptr = (*b & (1 << (bit & 7))) ? '1' : '0'; if (!(bit % 8)) b--; } dest[8 * size] = 0; return dest; } int main() { //char a = 'a'; //int a = 255; long long int a = 0xFFFFFFFFFFFFFFFF; char* bin_res = void2bin(&a, sizeof(a)); printf("a = %s\n", bin_res); free(bin_res); char ch = _getch(); return 0; } ![]() ![]() void TypeToBin(void* data, size_t size) { char* dest = (char*)malloc(1 + 8 * size); for (int i = size - 1; i >= 0; i--) { dest[i] = (*data & 1) + '0'; // ошибка *data >>= 1; // ошибка } dest[8 * size] = 0; return dest; } Прикреплённый файл ![]() |
Сообщ.
#2
,
|
|
|
Разименовывать void* нельзя. *data - ошибочное выражение, т.к. нельзя создать переменную типа void.
Если хотите так, то используйте char* Ну и вашей версии принципиальная ошибка. data >>= 1 никак не вяжется с циклом, т.к. цикл у вас по байтам. То есть вы фактически преобразуете только младший бит каждого байта. |
Сообщ.
#3
,
|
|
|
Цитата tumanovalex @ но ожидаемо получил ошибки в разиименованиях. Внимательно изучи работающий пример. Почему там нет ошибок, а у тебя есть ? Вот это: ![]() ![]() ...uint8_t*)(data) ... |
Сообщ.
#4
,
|
|
|
tumanovalex, при обработке больших данных, и если критична скорость обработки, лучше использовать вот такой подход (тут без контроля ошибки по выделению памяти):
![]() ![]() #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> // Таблица для преобразования байта в его строковое представление static const char* const lut[256] = { "00000000", "00000001", "00000010", "00000011", "00000100", "00000101", "00000110", "00000111", "00001000", "00001001", "00001010", "00001011", "00001100", "00001101", "00001110", "00001111", "00010000", "00010001", "00010010", "00010011", "00010100", "00010101", "00010110", "00010111", "00011000", "00011001", "00011010", "00011011", "00011100", "00011101", "00011110", "00011111", "00100000", "00100001", "00100010", "00100011", "00100100", "00100101", "00100110", "00100111", "00101000", "00101001", "00101010", "00101011", "00101100", "00101101", "00101110", "00101111", "00110000", "00110001", "00110010", "00110011", "00110100", "00110101", "00110110", "00110111", "00111000", "00111001", "00111010", "00111011", "00111100", "00111101", "00111110", "00111111", "01000000", "01000001", "01000010", "01000011", "01000100", "01000101", "01000110", "01000111", "01001000", "01001001", "01001010", "01001011", "01001100", "01001101", "01001110", "01001111", "01010000", "01010001", "01010010", "01010011", "01010100", "01010101", "01010110", "01010111", "01011000", "01011001", "01011010", "01011011", "01011100", "01011101", "01011110", "01011111", "01100000", "01100001", "01100010", "01100011", "01100100", "01100101", "01100110", "01100111", "01101000", "01101001", "01101010", "01101011", "01101100", "01101101", "01101110", "01101111", "01110000", "01110001", "01110010", "01110011", "01110100", "01110101", "01110110", "01110111", "01111000", "01111001", "01111010", "01111011", "01111100", "01111101", "01111110", "01111111", "10000000", "10000001", "10000010", "10000011", "10000100", "10000101", "10000110", "10000111", "10001000", "10001001", "10001010", "10001011", "10001100", "10001101", "10001110", "10001111", "10010000", "10010001", "10010010", "10010011", "10010100", "10010101", "10010110", "10010111", "10011000", "10011001", "10011010", "10011011", "10011100", "10011101", "10011110", "10011111", "10100000", "10100001", "10100010", "10100011", "10100100", "10100101", "10100110", "10100111", "10101000", "10101001", "10101010", "10101011", "10101100", "10101101", "10101110", "10101111", "10110000", "10110001", "10110010", "10110011", "10110100", "10110101", "10110110", "10110111", "10111000", "10111001", "10111010", "10111011", "10111100", "10111101", "10111110", "10111111", "11000000", "11000001", "11000010", "11000011", "11000100", "11000101", "11000110", "11000111", "11001000", "11001001", "11001010", "11001011", "11001100", "11001101", "11001110", "11001111", "11010000", "11010001", "11010010", "11010011", "11010100", "11010101", "11010110", "11010111", "11011000", "11011001", "11011010", "11011011", "11011100", "11011101", "11011110", "11011111", "11100000", "11100001", "11100010", "11100011", "11100100", "11100101", "11100110", "11100111", "11101000", "11101001", "11101010", "11101011", "11101100", "11101101", "11101110", "11101111", "11110000", "11110001", "11110010", "11110011", "11110100", "11110101", "11110110", "11110111", "11111000", "11111001", "11111010", "11111011", "11111100", "11111101", "11111110", "11111111" }; char* void2bin(void* data, size_t size) { char* dest = (char*)malloc(1 + 8 * size); char* ptr = dest; uint8_t* bytes = (uint8_t*)data; for (size_t i = 0; i < size; i++) { memcpy_s(ptr, 8, lut[bytes[size - 1 - i]], 8); ptr += 8; } * ptr = '\0'; return dest; } int main() { long long int a = 0x01FFFFFFFFFFFFFF; char* bin_res = void2bin( & a, sizeof(a)); printf("a = %s\n", bin_res); free(bin_res); return 0; } Да, и еще лучше не дергать выделение памяти в самой функции, а передавать указатель на уже заранее выделенный участок памяти для строкового представления. Ну или сделать дубль функции с внешним выделением. Вдруг придется переводить в двоично-строковое представление данные из таблицы со 100500 элементов ... ну не дёргать же память 100500 раз? |
![]() |
Сообщ.
#5
,
|
|
Иногда я думаю, ну зачем учить людей Cям, когда есть C++?..
![]() ![]() constexpr std::string TypeToBin(const auto& x) { return std::bitset<sizeof(x)*8>(x).to_string(); } |
Сообщ.
#6
,
|
|
|
Majestio и Qraizer, спасибо большое за объяснения и код!
|
![]() |
Сообщ.
#7
,
|
|
tumanovalex, помимо сказанного grgdvo и ЫукпШ, твоя функция не умеет принимать литералы, ей нельзя скормить константы, а главное – обнуляет свой параметр. Очень недальновидное архитектурное решение.
А кроме того, пример, который тебе кинули, плох. На киберфоруме, видать, сидят те ещё косяпоры, раз даже не предупредили тебя, что работать этот код будет только на little-endian платформах. Ну и положа руку на сердце, не везде байт восьмибитный. ![]() ![]() #include <limits.h> #include <stdbit.h> #if __STDC_ENDIAN_NATIVE__ != __STDC_ENDIAN_LITTLE__ && __STDC_ENDIAN_NATIVE__ != __STDC_ENDIAN_BIG__ #error Endianness has unknown format #endif char* TypeToBin(const void* data, size_t size) { char *dest = (char*)malloc(1 + CHAR_BIT*size), *value= (char*)data; int toNext= 1; #if __STDC_ENDIAN_NATIVE__ == __STDC_ENDIAN_LITTLE__ value += size - 1; toNext =-1; #endif for (int j = 0; j < size; ++j) { unsigned char byte = *value; for (int i = CHAR_BIT-1; i >= 0; --i) { dest[j*CHAR_BIT + i] = (byte & 1) + '0'; byte >>= 1; } value += toNext; } dest[CHAR_BIT*size] = 0; return dest; } Добавлено Что-то типа ![]() ![]() _Bool isLittle(void) { long long check = 1; const char *ptr = (const char*)✓ return *ptr == '\1'; } |
Сообщ.
#8
,
|
|
|
Цитата Qraizer @ Иногда я думаю, ну зачем учить людей Cям, когда есть C++?.. ![]() ![]() constexpr std::string TypeToBin(const auto& x) { return std::bitset<sizeof(x)*8>(x).to_string(); } Сам же попался на том, о чем меня поправлял в соседней теме ![]() У чела в теме "универсальная" функция, а в объявлении char* void2bin(void* data, size_t size). Если в твою функцию подать к примеру char[256], твой конструктор битсета взмолится, максимум long long. Или строку из STL. Эх ты ![]() |
![]() |
Сообщ.
#9
,
|
|
Универсальная функция не рассчитана на составные типы, да. Ну так у ТС то же самое. Самое время у него уточнить, конечно, а то мало ли. И даже при этом непонятно, как быть с вещественными. Добавь концепт std::integral, если хочешь.
|
Сообщ.
#10
,
|
|
|
Цитата Qraizer @ А кто такой ТС? Ну так у ТС то же самое. Самое время у него уточнить, конечно, а то мало ли. |
![]() |
Сообщ.
#11
,
|
|
Ты
![]() |
Сообщ.
#12
,
|
|
|
Я имел ввиду отрицательные и положительные целые числа и char. Я думал, что получить битовое представление составных типов и вещественных чисел нельзя.
|
![]() |
Сообщ.
#13
,
|
|
Можно, но смысла в этом немного. Особенно составных.
|
Сообщ.
#14
,
|
|
|
Цитата tumanovalex @ Я думал, что получить битовое представление составных типов и вещественных чисел нельзя. Наводящий вопрос: Как же тогда их умудряется сохранять в памяти компьютер? Но я согласен. Смысл печатать двоичное представление для вещественных или составных чисел нету. Шестнадцатеричное представление еще полезно, а вот двоичное уже точно нет. |
Сообщ.
#15
,
|
|
|
Цитата macomics @ Наводящий вопрос: Как же тогда их умудряется сохранять в памяти компьютер? ![]() |