Форум программистов
 
Регистрация на форуме тут, о проблемах пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail, а тут можно восстановить пароль

Купить рекламу на форуме 15-35 тыс рублей в месяц

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Ответ
 
Опции темы Поиск в этой теме
Старый 17.03.2013, 21:09   #1
doojkee
Пользователь
 
Регистрация: 08.04.2012
Сообщений: 10
Восклицание Битовые операции на чистом Си

Добрый вечер, форумчане, нужна ваша помощь, никак не могу додуматься, как сделать это задание:

Цитата:
Установить в заданные пользователем значения некоторые разряды, количество которых и номера разрядов задаются с клавиатуры.

Более подробно:

1.вводим число
2.переводим его в 2ую систему
3.вводим 1 или 0
4.вводим число разрядов
5.вводим номера разрядов
6.заменяем в введенных разрядах значения 1 или 0 (в зависимости, от того, что мы ввели в п.3);
7.выводим измененное число


Задание нужно выполнить на чистом Си.
Вот мои наработки:

Код:
#include <stdio.h>
#include <conio.h>
#include <windows.h>

int output(char x[]){
    int i,j;
    for (i = 7; i >-1; i--)
        for (j = 7; j >-1; j--){
            printf("%d",(x[i]>>j)&1);
            }
    printf("\n");
}


int main(){
    int i,n_bit,k_num_bits, number;
    system("cls");

    union{
        double m;
        char a[8];
    }type;


printf("Enter the number: ");
scanf("%lf", &type.m);

output(type.a);

printf("Enter the '1' or '0': ");
scanf("%d", &number);

    printf("Enter the numbers of bits: ");
    scanf("%d", &n_bit);

    for(i = 0;i < n_bit;i++){
        printf("Enter the number of bits: ");
        scanf("%d",&k_num_bits);
        type.a[k_num_bits/8] = type.a[k_num_bits/8]^(1<<(k_num_bits-8*(k_num_bits/8)));
    }

printf("\n");
output(type.a);
printf("\n");

printf("\nResult is:  -> %lf ", type.m);

getch();
return 0;

}
В моей коде работает все, только для введенного значения 1, если 0, я не знаю, как дописать этот функционал!
Надеюсь на вашу помощь!
doojkee вне форума Ответить с цитированием
Старый 17.03.2013, 22:00   #2
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 6,841
По умолчанию

Код:
#include <stdio.h>
#include <conio.h>
#include <windows.h>

int
output(long int x)
{
    int i;
    for (i = 8 * sizeof(x) -1; i > -1; i--)
        printf("%d",(x>>i)&1);
    printf("\n");
}

int
main()
{
    system("cls");

    long int a;
    printf("Enter the number: ");
    scanf("%ld", &a);
    output(a);

    int num;
    printf("Enter the '1' or '0': ");
    scanf("%d", &num);

    int count;
    printf("Enter count of bits: ");
    scanf("%d", &count);

    int i;
    for(i = 0; i < count; ++i)
    {
        int pos;
        printf("Enter the position of editing bits: ");
        scanf("%d", &pos);
        if (num)
            a |= 1 << pos;
        else {
            unsigned long int mask = ~(1 << pos);
            a &= mask;
        }
    }
    printf("\n");
    output(a);
    printf("Result is:  -> %ld ", a);

    getch();
    return 0;
}
Проверьте.
Нумерация битов от младшего к старшему, начиная с 0 (справа налево, если смотреть на текстовое представление).
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 17.03.2013, 22:11   #3
doojkee
Пользователь
 
Регистрация: 08.04.2012
Сообщений: 10
По умолчанию

исходное задание делается для типа данных double(long doble)
В вашем коде, при попытке ввода числа 15.375 наблюдаю такую картину наблюдаю такую картину

Последний раз редактировалось doojkee; 17.03.2013 в 22:56.
doojkee вне форума Ответить с цитированием
Старый 17.03.2013, 22:53   #4
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 6,841
По умолчанию

Я думал, что использование double, просто Ваша прихоть.
Предыдущий код работает только с целыми числами.
Код:
#include <stdio.h>
#include <conio.h>
#include <windows.h>

typedef union{
    double m;
    char a[8];
} mt;

int
output(mt x)
{
    int i;
    for (i = 8 * sizeof(x) - 1; i > -1; i--)
        printf("%d",(x.a[i/8]>>(i%8))&1);
    printf("\n");
}

int
main()
{
    system("cls");

    mt f;
    printf("Enter the number: ");
    scanf("%lf", &f.m);
    output(f);

    int num;
    printf("Enter the '1' or '0': ");
    scanf("%d", &num);

    int count;
    printf("Enter count of bits: ");
    scanf("%d", &count);

    int i;
    for(i = 0; i < count; ++i)
    {
        int pos;
        printf("Enter the position of editing bits: ");
        scanf("%d", &pos);
        if (num)
            f.a[pos/8] |= 1 << pos%8;
        else {
            unsigned char mask = ~(1 << pos%8);
            f.a[pos/8] &= mask;
        }
    }
    printf("\n");
    output(f);
    printf("Result is:  -> %lf\n", f.m);

    getch();
    return 0;
}
Тут более сложная схема установки бита.
Разберу способ на предыдущем коде.
Если нужно поставить k-й бит в единицу, то получаем число с k-м единичным битом и остальными нулями (1 << k). Затем делаем побитовое "или" с исходным числом, тем самым "поднимая" требуемый бит.
Если нужно, наоборот, опустить k-й бит, то нужно создать битовую маску из единиц, в которой на месте требуемого бита будет 0. Сначала получаем число, в котором на k-ом месте стоит единица, затем инвертируем биты и получаем требуемую маску. Побитовое "и" "опустит" k-й бит.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 17.03.2013 в 22:58.
BDA вне форума Ответить с цитированием
Старый 17.03.2013, 22:58   #5
doojkee
Пользователь
 
Регистрация: 08.04.2012
Сообщений: 10
По умолчанию

Если вам не сложно, не могли бы прокомментировать данный цикл, что в нем происходит и каким образом!

Код:
for(i = 0; i < count; ++i)
    {
        int pos;
        printf("Enter the position of editing bits: ");
        scanf("%d", &pos);
        if (num)
            f.a[pos/8] |= 1 << pos%8;
        else {
            unsigned char mask = ~(1 << pos%8);
            f.a[pos/8] &= mask;
        }
    }
и вот этот кусочек

Код:
printf("%d",(x.a[i/8]>>(i%8))&1);

Желательно поподробней, спасибо!
Я просто только учусь программировать на Си, поэтому для меня многие моменты не до конца ясны.

Последний раз редактировалось doojkee; 17.03.2013 в 23:24.
doojkee вне форума Ответить с цитированием
Старый 17.03.2013, 23:06   #6
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 6,841
По умолчанию

Во-первых, не цитируйте полностью такие длинные сообщения.
Во-вторых, само объяснение:


Верхняя строка - то, как мы привыкли видеть нумерацию битов в числе, когда записываем их на бумаге.
Нижняя строка - как на самом деле будут храниться байты в памяти (так называемый little-endian - порядок от младшего к старшему).
То есть первый (нулевой в нумерации Си) байт массива "а" будет хранить самый младший байт числа "m".
Для вывода числа мы идем циклом от самого большого номера бита к самому маленькому.
Нам нужно брать правильный бит из правильного байта.
По картинке несложно заметить, что целая часть от номера i указывает на требуемый байт, а остаток - на нужный бит.

UPD
Пожалуйста
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 17.03.2013 в 23:22.
BDA вне форума Ответить с цитированием
Старый 17.03.2013, 23:18   #7
doojkee
Пользователь
 
Регистрация: 08.04.2012
Сообщений: 10
По умолчанию

Прошу прощения за тупые вопросы, но все же хочу до конца разобраться!
(i%8), что это операция?
Операции |= и &=, интерпретируются так как и +=?

Последний раз редактировалось doojkee; 17.03.2013 в 23:29.
doojkee вне форума Ответить с цитированием
Старый 17.03.2013, 23:25   #8
Smitt&Wesson
Старожил
 
Аватар для Smitt&Wesson
 
Регистрация: 31.05.2010
Сообщений: 13,965
По умолчанию

BDA, прикалываешься что-ли?
В "чистом C нет++). Это С++
Для "чистого" С, a = a+1;
Пиши пьяным, редактируй трезвым.
Справочник по алгоритмам С++ Builder

Последний раз редактировалось Smitt&Wesson; 17.03.2013 в 23:28.
Smitt&Wesson вне форума Ответить с цитированием
Старый 17.03.2013, 23:34   #9
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 6,841
По умолчанию

doojkee, i%8 - остаток i от деления на 8.
|= и &= работают также (одинаковая семантика, вроде так это называется ), как и +=, т.е. a |= 2 то же самое, что и a = a|2.

Smitt&Wesson, честно говоря, первый раз такое слышу - полтора года пишу ++, компилирую в gcc и думаю, что пишу на чистом Си.
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )

Последний раз редактировалось BDA; 17.03.2013 в 23:38.
BDA вне форума Ответить с цитированием
Старый 17.03.2013, 23:41   #10
doojkee
Пользователь
 
Регистрация: 08.04.2012
Сообщений: 10
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
doojkee, i%8 - остаток i от деления на 8.
|= и &= работают также (одинаковая семантика, вроде так это называется ), как и +=, т.е. a |= 2 то же самое, что и a = a|2.

Smitt&Wesson, честно говоря, первый раз такое слышу - полтора года пишу ++, компилирую в gcc и думаю, что пишу на чистом Си.
Еще раз благодарю вас, очень помогли!
Последний тупой вопрос, для чего мы проверяем на остаток делания на 8?
doojkee вне форума Ответить с цитированием
Ответ
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Битовые операции(с++) Lazy maximka Помощь студентам 2 23.12.2010 18:55
Битовые операции СИ savra Помощь студентам 0 10.03.2010 19:31
Битовые операции ("")(Э_Є)("") Общие вопросы C/C++ 4 03.07.2009 19:15
Битовые операции DrAlexx2121 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 4 14.06.2008 22:26