Разбить строку по 8 бит и перевести
Дана последовательность из ? битов, каждый бит имеет значение 0 или 1. Нужно разделить эту последовательность на байты, по 8 битов в каждом (в последний байт может попасть меньше битов). После этого нужно распечатать значения всех полученных байтов в привычной людям десятичной системе исчисления. Биты внутри байта записываются в привычном современным компьютерам порядке little-endian: сначала идут младшие биты, потом старшие. В первой строке входного файла записано одно целое число ? — количество битов в последовательности. Во второй строке записано ровно ? символов 0 или 1: значения битов последовательности. после второй строки файла символ перевода строки может быть, а может не быть. Мой код представлен ниже. Сколько ни бьюсь с ним - неверный ответ на выходе. Подскажите тупящему новичку, что можно сделать/исправить?
#include<stdio.h>
#include<math.h>
int main(){
int N, i, v;
scanf("%d", &N);
int p[N-1];
for (i=0; i<=N-1; i+=8){
v=((p[i]*(pow(2,i)))+(p[i+1]*(pow(2,(i+1))))+(p[i+2]*(pow(2,(i+2))))+(p[i+3]*(pow(2,(i+3))))+(p[i+4]*(pow(2,(i+4))))+(p[i+5]*(pow(2,(i+5))))+(p[i+6]*(pow(2,(i+6))))+(p[i+7]*(pow(2,(i+7)))));
printf("%d", v);
}
}
Ответы (2 шт):
тихий ужас :)
во-первых вместо pow(2, i) лучше использовать 1 << i - т.е. битовое смещение 1чки вправо - это равносильно возведению в степень 2, только ГОРАЗДО быстрее и не требует подключения дополнительных библиотек
Как бы я сделал алгоритм:
перемещаемся в цикле по 8 и накапливаем байт
value = 0; for (int index = 0; index < 8; index ++) value += buf[index] << index;по буферу
pшел бы с через предыдущий циклint pos = 0; while (pos < N) { int* buf = (int*)p + pos; value = 0; for (int index = 0; index < 8; index ++) value += buf[index] << index; pos += 8; }и конечно надо учесть, что на последнем байте может потребоваться менее 8 шагов цикла:
const int size = (N - pos >= 8) ? 8 : (N - pos);
В итоге алгоритм был бы таким:
int pos = 0;
while (pos < N) {
int* buf = (int*)p + pos;
const int size = (N - pos >= 8) ? 8 : (N - pos);
value = 0;
for (int index = 0; index < pos; index ++)
value += buf[index] << index;
// тут выводим value в требуемом виде
pos += 8;
}
Конечно считаем, что в массиве p уже записаны числа
Если в нем записаны буквы, тогда надо так:
int pos = 0;
while (pos < N) {
char* buf = (char*)p + pos;
const int size = (N - pos >= 8) ? 8 : (N - pos);
value = 0;
for (int index = 0; index < pos; index ++) {
const int bit = (buf[index] == '0') ? 0 : 1;
value += bit << index;
}
// тут выводим value в требуемом виде
pos += 8;
}
P.S.
если я не перепутал бигэниан и литлэндиан, иначе придется так:
value += buf[index] << (7 - index);
Попробуйте так:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
int main(void)
{
size_t N = 0;
scanf("%zu", &N);
size_t num_of_bytes = N / 8 + (N % 8 != 0);
uint_least8_t* buff = malloc(num_of_bytes * sizeof(uint_least8_t));
if (!buff)
return EXIT_FAILURE;
int buff_pos = 0;
int byte = 0, digit_shift = 0, digit = 0;
for (size_t i = 0; i < N; ++i)
{
scanf("%1d", &digit);
byte += digit << digit_shift;
++digit_shift;
if (digit_shift == 8)
{
buff[buff_pos] = byte;
++buff_pos;
byte = 0;
digit_shift = 0;
}
}
if (N % 8 != 0)
buff[buff_pos] = byte;
for (size_t i = 0; i < num_of_bytes; ++i)
printf("%" PRIuLEAST8 " ", buff[i]);
free(buff);
return 0;
}
Пример ввода:
27
11111111 00000001 01010101 011
255 128 170 6