Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.78/41: Рейтинг темы: голосов - 41, средняя оценка - 4.78
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27

Зачем нужные поразрядные операции. Книга Павловская, Щупак

19.08.2009, 21:02. Показов 7911. Ответов 35
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Решаю задачу из учебника Павловская, Щупак. С++. Программироание на языке высокого уровня. Структурное программирование. Практикум. Часть 1. Семинар 2. Задача 1. стр. 44. Задачу см. в привязанном файле.

Кажется, я решила задачу, программа работает. Но мне не понятно, зачем авторы пишут про поразрядные операции И и ИЛИ. Мне удалось обойтись без них. Может кто-нибудь объяснить, почему речь идет о поразрядных операциях?
Вот мой код. Вроде, работает.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
using namespace std;
 
int main()
{
    float a = 1, b = 2, c = 3;//действительные числа
    float Xn, Xk, dX, f;//значения функции (начальное, конечное, дельта, результат)
    cout << "Vvedite Xn, Xk, dX: ";
    cin >> Xn >> Xk >> dX;
    cout << "a = " << a << " b = " << b << " c = " << c << endl; 
    cout << "Xn = " << Xn << " Xk = " << Xk << " dX = " << dX << endl; 
    cout << "-----------------" << endl;
    cout << "|   X   |   F   |" << endl;
    cout << "-----------------" << endl;
    for(float x = Xn; x <= Xk; x += dX)
    {
        if(x < 0 && b != 0)
        {   
            f = a*x*x+b;
            cout << "f (x < 0 && b !=0): " << f << endl;
        }
        if(x > 0 && b == 0)
            {
                if(x == c) 
                {
                    cout << "NULL";
                    return 0;
                }
                else 
                {
                    f = (x-a)/(x-c);
                    cout << "f (x > 0 && b == 0): " << f << endl;
                }
            }
        if(x == 0 || (x < 0 && b == 0) || (x > 0 && b != 0))
            {
                f = x/c;
                cout << "f: " << f << endl;
            }
    }
return 0;
}
Заранее спасибо.
Миниатюры
Зачем нужные поразрядные операции. Книга Павловская, Щупак  
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.08.2009, 21:02
Ответы с готовыми решениями:

Правильно ли я написал программу? Из книжки Павловская Щупак
Задание во вложении, вот не могу разобраться, помогите, правильно ли написана программа? #include &lt;iostream&gt; #include...

Книга Юрий Щупак Win32 API. Разработка приложений для Windows
Остался ли источник где можно скачать - Win32 API. Разработка приложений для Windows ???

Поразрядные операции
Написать функцию, которая в числе x устанавливает 0 в n бит, находящихся справа от позиции p, остальные биты остаются без изменения.

35
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
19.08.2009, 21:10
Функция F должна принимать действительное значение, если выражение (А ИЛИ В) И (А ИЛИ С) не равно нулю, и целое в противном случае
в жалком подобии кода это значит грубо говоря это
C++
1
2
3
4
if(((A | B) & (A | C)) != 0)
    return float;
else
    return int;
Если не прав - исправте меня
2
640KB мне хватило на всё.
119 / 50 / 3
Регистрация: 07.06.2009
Сообщений: 442
19.08.2009, 21:41
Поразрядные операции могут заменить "обычные логические".
Смысла для вашей задачи нет. Поразрядные операции целесообразны при работе с полями битов (массивы флагов или т.п.) которые представляют сразу несколько значений (сущностей) к которым надо применить единое правило. Классический пример - на адрес "наложить" маску, что бы выделить нужные биты (часть адреса).

В общем, это обычная ерунда препода составлявшего методичку (просто невозможно придумать задачу одновременно достаточно простую и практически релевантную).
Сама задача рассчитана на изучение ветвления - использование оператора if или case/swith. Но, дополнительна "утяжелена" необходимостью выделения целой части, при условии (Ац ИЛИ Вц)И(Ац ИЛИ Сц). Последнюю часть Вы пропустили.

Плюс, сделали ошибку в теле for - у Вас три оператора if идут последовательно, а должны быть вложены.
C++
1
2
3
if ( ) { } // Первое условие и вычисление
else if ( ) { } // Второе условие и вычисление
     else { } // Вычисление по третьему условию без проверки
0
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
19.08.2009, 21:49  [ТС]
Переделала в соответствии с вашими советами. Подозреваю, что упустила часть задачи. Первоначальный вариант просто считает F исходя из начальных условий, но упускает тот факт, что результаты в таблицу нужно выводить исходя из последнего условия (А ИЛИ В) И (А ИЛИ С).
Посмотрите новый вариант. Сейчас это является решением задачи или нет?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <iostream>
using namespace std;
 
int main()
{
    float a = 1.2f, b = 2.3f, c = 3;//действительные числа
    float Xn, Xk, dX, f;//значения функции (начальное, конечное, дельта, результат)
    cout << "Vvedite Xn, Xk, dX: ";
    cin >> Xn >> Xk >> dX;
    cout << "a = " << a << " b = " << b << " c = " << c << endl; 
    cout << "Xn = " << Xn << " Xk = " << Xk << " dX = " << dX << endl; 
    cout << "-----------------" << endl;
    cout << "|   X   |   F   |" << endl;
    cout << "-----------------" << endl;
    if(((int(a) | int(b)) & (int(a) | int(c))) != 0)
    {
        for(float x = Xn; x <= Xk; x += dX)
        {
            if(x < 0 && b != 0)
            {   
                f = a*x*x+b;
                cout << "f (x < 0 && b !=0): " << f << endl;
            }
            else
            {
                if(x > 0 && b == 0)
                {
                    if(x == c) 
                    {
                        cout << "NULL";
                        return 0;
                    }
                    else 
                    {
                        f = (x-a)/(x-c);
                        cout << "f (x > 0 && b == 0): " << f << endl;
                    }
                }
                else            
                {
                    f = x/c;
                    cout << "f: " << f << endl;
                }
            }
        }
    }
    else
    {
        for(float x = Xn; x <= Xk; x += dX)
        {
            if(x < 0 && b != 0)
            {   
                f = int(a)*x*x+int(b);
                cout << "f (x < 0 && b !=0): " << f << endl;
            }
            else
            {
                if(x > 0 && b == 0)
                {
                    if(x == c) 
                    {
                        cout << "NULL";
                        return 0;
                    }
                    else 
                    {
                        f = (x-int(a))/(x-int(c));
                        cout << "f (x > 0 && b == 0): " << f << endl;
                    }
                }
                else            
                {
                    f = x/int(c);
                    cout << "f: " << f << endl;
                }
            }
        }           
    }
return 0;
}
0
640KB мне хватило на всё.
119 / 50 / 3
Регистрация: 07.06.2009
Сообщений: 442
19.08.2009, 22:02
Кашмар!
Не знаю, будет работать или нет! Но зачёт за такое поставит только урод.
Само решение должно состоять из двух частей - (1) вычисление функции, (2) - "возможное" отбрасывание дробной части.
А Вы сделали оператор выбора отбрасывания/неотбрасывания дробной части, и в каждую из этих ветвей вставили код, вычисляющий функцию.
Но тело цикла исправили верно. Хотя, сам вывод ёще какой-то корявый и бессмысленный.
Судя по наличию шапки таблицы, операторы типа
cout << "f (x < 0 && b !=0): " << f << endl;
следует заменить на что-то типа
cout << "|" << x << "|"<< f << "|"<<endl; //и добавить выравнивание
0
556 / 510 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
19.08.2009, 22:09
а зачем так сложно? ведь в условии ясно сказано:

C++
1
2
3
4
5
6
7
if(x < 0 && b != 0){
... делай раз
} else if(x > 0 && b == 0){
... делай два
} else {
... делай три
}
в принципе можно здесь тоже применить поразрядные операции, но глупо и платформозависимо. наверное это ошибка в условии. человек и имел ввиду логические операции сравнения.
0
640KB мне хватило на всё.
119 / 50 / 3
Регистрация: 07.06.2009
Сообщений: 442
19.08.2009, 23:15
Цитата Сообщение от novi4ok Посмотреть сообщение
а зачем так сложно?
Задачку до конца дочитайте. Я тоже сперва на выражение посмотрел и долго тупил.
0
556 / 510 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
20.08.2009, 00:36
Цитата Сообщение от skvor Посмотреть сообщение
Задачку до конца дочитайте. Я тоже сперва на выражение посмотрел и долго тупил.
и действительно... заморочка. но что означает "функция принимает целое значение"? мы сейчас можем долго спорить на эту тему, т.к. существует не один способ как это можно истолковать.
кроме того, нигде не стоит, что начальное, конечное значения и интервал - действительные числа (кстати, в реализации отсутствует проверка на то, что начальное значение меньше конечного, что допускает бесконечный, или по крайней мере очень длинный цикл).
пример толкований:
0. если ля-ля-ля равно нулю, исходные данные преобразуются в целые, дальше - все по целочисленной арифметике.
1. если ля-ля-ля равно нулю, конечный результат преобразуется в целое.
2. если ля-ля-ля равно нулю, конечный результат округляется по правилам округления до ближайшего целого.
3. если ля-ля-ля равно нулю, исходные данные округляется по правилам округления до ближайшего целого, дальше - по целочисленной арифметике.
...
0
640KB мне хватило на всё.
119 / 50 / 3
Регистрация: 07.06.2009
Сообщений: 442
20.08.2009, 00:41
novi4ok, ну, скорее, надо выделять целую часть по "машинным понятиям"
Хотя это не суть, если что - светит замена только одного оператора.
А вот для Aц и других - логичнее именно выделение целой части и работа с ними как с битовыми полями или типа того.
0
Эксперт JavaЭксперт С++
 Аватар для M128K145
8384 / 3617 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
20.08.2009, 01:01
Цитата Сообщение от skvor Посмотреть сообщение
Плюс, сделали ошибку в теле for - у Вас три оператора if идут последовательно, а должны быть вложены.
Какая разница? Это не ошибка. Ну не выполнилось условие - программа пошла дальше и наткнулась на новое условие, проверила и так далее. Зачем else ставить? Здесь он не нужен.
Цитата Сообщение от skvor Посмотреть сообщение
Кашмар!
Не знаю, будет работать или нет! Но зачёт за такое поставит только урод.
Человек попросил о помощи. Я понимаю, возможно ты знаеш больше чем Biblio, но зто не повод так эмоционально на все ошибки реагировать. Представь, если б на все ошибки которые ты допускаеш так реагировали, тебе бы тоже это не нравилось.
0
640KB мне хватило на всё.
119 / 50 / 3
Регистрация: 07.06.2009
Сообщений: 442
20.08.2009, 01:07
Цитата Сообщение от M128K145 Посмотреть сообщение
Человек попросил о помощи. Я понимаю, возможно ты знаеш больше чем Biblio, но зто не повод так эмоционально на все ошибки реагировать. Представь, если б на все ошибки которые ты допускаеш так реагировали, тебе бы тоже это не нравилось.
Опять по диагонали читаете - то была потенциальная оценка человека, готового поставить зачёт.
Для меня препод-урод - не тот кто студентов пинает, а тот, кто ставит зачёты не за знания по предмету. И эта оценка преподов не зависит от того, является ли его предмет профильным или общеинженерной ("ненужной") дисциплиной.
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
20.08.2009, 05:48
C++
1
cout << "f (x < 0 && b !=0): " << f << endl;
это нужно разделить

C++
1
cout << "f (x < 0 && b !=0): ";
C++
1
cout << f << endl;
потом

C++
1
cout << (IntParts(a, b, c) ? (long) f : f) << endl;
C
1
2
3
4
5
6
int IntParts(int a, int b, int c)
{
    /* (a || b) && (a || c) */
 
    return (a | b) & (a | c) & 1;
}
то есть, вывод f должен быть только один, а случаи просто считают как надо и выводят сообщение; сообщение можно цеплять к указателю - тогда его можно выводить вместе с f

там выше M128K145 уже написал побитовые операции, так что & 1 просто для плавности
0
640KB мне хватило на всё.
119 / 50 / 3
Регистрация: 07.06.2009
Сообщений: 442
20.08.2009, 06:45
Лучший ответ Сообщение было отмечено как решение

Решение

accept, попробуйте скомпилировать
cout << (IntParts(a, b, c) ? (long) f : f) << endl;
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
20.08.2009, 08:18
C++
1
cout << (IntParts((int) a, (int) b, (int) c) ? (long) f : f) << endl;
явное приведение, вообще оно приводит к типам в прототипе
поэтому можно делать free(p); без приведения

Добавлено через 1 час 5 минут 15 секунд
для C++ всё таки обязательно приводить, потому что там бывают перегруженные функции и от типов аргументов зависит какой из вариантов одной функции должен сработать
0
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
20.08.2009, 12:21  [ТС]
Спасибо всем огромное за комментарии. Если я правильно понимаю, вся загвоздка задачи в этой фразе: "Функция F должна принимать действительное значение, если выражение (Ац ИЛИ Вц) И (Ац ИЛИ Сц) не равно нулю, и целое в противном случае".
Я ее понимаю так:
Функция F должна быть равна действительному (вещественному, т.е. в нашем случае float числу), если выражение (Ац ИЛИ Вц) И (Ац ИЛИ Сц) НЕ РАВНО нулю, и F должна быть равна целому числу (в нашем случае int), если выражение (Ац ИЛИ Вц) И (Ац ИЛИ Сц) РАВНО нулю. При этом выражение (Ац ИЛИ Вц) И (Ац ИЛИ Сц), содержит поразрядные операции, т.е. фактически в нем вычисляется булево выражение (A&B)|(A&C) которое проверяется на равенство нулю.
Я переделала код, только теперь не знаю, как проверить, правильно ли он работает. Если выражение (Ац ИЛИ Вц) И (Ац ИЛИ Сц) считает нолики и единицы, то как мне проверить правильность работы программы? У меня это выражение всегда не равно нулю.
Плюс, у программы странное поведение при переходе через ноль. При значениях дельты 0.1, 0.2, 0.4 при переходе через ноль в значение функции попадает какой-то мусор. При других значениях дельты выражение f=x/c считается нормально, т.е. f= 0
Вот мой новый вариант:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
using namespace std;
 
int main()
{
    float a = 1.2f, b = 2.3f, c = 3;//действительные числа
    float Xn, Xk, dX, f;//значения функции (начальное, конечное, дельта, результат)
    cout << "Vvedite Xn, Xk, dX: ";
    cin >> Xn >> Xk >> dX;
    if(Xk<=Xn)
    {
        cout << "Ntpravilno vvedeni dannie. Xk ne m/b < Xn\n";
        cout << "Vvedite Xn, Xk, dX: ";
        cin >> Xn >> Xk >> dX;
    }
    cout << "a = " << a << " b = " << b << " c = " << c << endl; 
    cout << "Xn = " << Xn << " Xk = " << Xk << " dX = " << dX << endl; 
    cout << "-----------------" << endl;
    for(float x = Xn; x <= Xk; x += dX)
    {
        //Вычисление функции
        if(x < 0 && b != 0)
        {   
            f = a*x*x+b;
            cout << "При х = " << x << "; f (x < 0 && b !=0) = " << f << endl;
        }
        else
        {
            if(x > 0 && b == 0)
            {
                if(x == c) 
                {
                    cout << "На ноль делить нельзя";
                    return 0;
                }
                else 
                {
                    f = (x-a)/(x-c);
                    cout << "При х = " << x << "; f (x > 0 && b == 0) = " << f << endl;
                }
            }
            else            
            {
                f = x/c;
                cout << "При х = " << x << "; f = " << f << endl;
            }
        }
        //Приведение ее к нужному значению в связи с условием.
        if(((int(a) | int(b)) & (int(a) | int(c))) != 0)
        {
            cout << "Неприведенное значение F = " << f << "   |\n";
            cout << "-----------------" << endl;
        }
        else
        {
            cout << "При х = " << x << " Приведенное значение F = " << int(f) << "   |\n";
            cout << "-----------------" << endl;
        }
 
    }
return 0;
}
Простите за дотошность. Просто хочется понять задачу.
Для
Цитата Сообщение от skvor Посмотреть сообщение
Кашмар!
В августе зачеты никто не ставит. Есть еще просто интерес
0
640KB мне хватило на всё.
119 / 50 / 3
Регистрация: 07.06.2009
Сообщений: 442
20.08.2009, 20:12
Цитата Сообщение от Biblio Посмотреть сообщение
В августе зачеты никто не ставит. Есть еще просто интерес
Да-а, а я думал на осень хвост оставили

Относительно мусора - непонятно, где, через какой ноль, кто переходит?
М.б. проблема в том, что прибавляя к целому отрицательному дельту 0.1 не возникает условия равенства нулю. Например если к -1 десять раз прибавить 0.1, то нуля не будет - получится что-то очень близкое к нулю, но не ноль. Это особенность процессорного представления десятичных дробей, которые невозможно точно представить двоичными числами. В результате, при значении аргумента близкого к нулю вы проходите ветвь с делением, а деление на "очень" малое, приводит к переполнению. Но это только предположение.
0
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
20.08.2009, 20:15  [ТС]

Спасибо. Проверю ваше предположение. А про общее решение задачи что скажете? Правильно я ее понимаю или нет?
0
640KB мне хватило на всё.
119 / 50 / 3
Регистрация: 07.06.2009
Сообщений: 442
20.08.2009, 20:55
1) Не стоит в if(...) сравнивать с нулём - любое выражение/значение при равенстве нулю - соответствует false, при неравенстве - true
Т.е. if(x > 0 && b == 0) можно заменить на if(x > 0 && b) и переставить ветви then-else
Аналогично (x < 0 && b != 0) тождественно (x < 0 && b)

2) Нелогично для табуляции задавать интервал и приращение.
Нужно либо
- Интервал табуляции (начало и конец) и число шагов
- Начальная точка, шаг (приращение) и число шагов
0
229 / 67 / 11
Регистрация: 02.06.2009
Сообщений: 280
20.08.2009, 21:06
Кажется, я решила задачу, программа работает. Но мне не понятно, зачем авторы пишут про поразрядные операции И и ИЛИ. Мне удалось обойтись без них. Может кто-нибудь объяснить, почему речь идет о поразрядных операциях?
Странно что никто не ответил.

Потому что логические и порязрядные операции дают разные результаты.
0xF0 && 0x0F -> true
0xF0 & 0x0F -> false
1
640KB мне хватило на всё.
119 / 50 / 3
Регистрация: 07.06.2009
Сообщений: 442
20.08.2009, 21:25
Цитата Сообщение от Alexandoros Посмотреть сообщение
Потому что логические и порязрядные операции дают разные результаты.
Оператор разыменовывания указателя и вычисление квадратного корня, тоже дают разные результаты.
Мотивы автора уже не определить. Но мысль правильная.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.08.2009, 21:25
Помогаю со студенческими работами здесь

Поразрядные операции
^- что значи этот знак в с++

Поразрядные операции
Написать программу на языке С++, в которой создать: - массив из n элементов типа unsigned int (значение n вводится с клавиатуры) и...

Поразрядные операции
Даны два int-числа: N1 = ABCD и N2 = EFGH, где AB…GH – 16 – ричные цифры. Образовать long-число ABEFCDGH, используя только поразрядные...

Поразрядные операции
Даны два int-числа: N1 = ABCD и N2 = EFGH, где AB…GH – 16 – ричные цифры. Образовать long-число DEGHDABF, используя только поразрядные...

Поразрядные операции
Здравствуйте. Объясните, пожалуйста, есть задача: выполнить поразрядное «или» 0-5 разрядов В и 0-3 разрядов С, сдвинутых вправо на 2...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru