Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 41, средняя оценка - 4.90
Biblio
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
#1

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

19.08.2009, 21:02. Просмотров 5264. Ответов 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)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.08.2009, 21:02
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Зачем нужные поразрядные операции. Книга Павловская, Щупак (C++):

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

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

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

Поразрядные операции - C++
Обьясните пожалуйста работу поразрядных операций (&amp;, |, ^, &lt;&lt;, &gt;&gt;, ~). Например, n=n&amp;0177; - обнуляет все биты переменной N, кроме младших...

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

поразрядные операции - C++
помогите пожалуйста решить следущую задачу: даны два int-числа: N1 = АBCD и N2 = EFGH, где AB…GH – 16-ричные цифры, ПОп –...

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

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

Плюс, сделали ошибку в теле for - у Вас три оператора if идут последовательно, а должны быть вложены.
C++
1
2
3
if ( ) { } // Первое условие и вычисление
else if ( ) { } // Второе условие и вычисление
     else { } // Вычисление по третьему условию без проверки
0
Biblio
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
19.08.2009, 21:49  [ТС] #4
Переделала в соответствии с вашими советами. Подозреваю, что упустила часть задачи. Первоначальный вариант просто считает 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
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
19.08.2009, 22:02 #5
Кашмар!
Не знаю, будет работать или нет! Но зачёт за такое поставит только урод.
Само решение должно состоять из двух частей - (1) вычисление функции, (2) - "возможное" отбрасывание дробной части.
А Вы сделали оператор выбора отбрасывания/неотбрасывания дробной части, и в каждую из этих ветвей вставили код, вычисляющий функцию.
Но тело цикла исправили верно. Хотя, сам вывод ёще какой-то корявый и бессмысленный.
Судя по наличию шапки таблицы, операторы типа
cout << "f (x < 0 && b !=0): " << f << endl;
следует заменить на что-то типа
cout << "|" << x << "|"<< f << "|"<<endl; //и добавить выравнивание
0
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
19.08.2009, 22:09 #6
а зачем так сложно? ведь в условии ясно сказано:

C++
1
2
3
4
5
6
7
if(x < 0 && b != 0){
... делай раз
} else if(x > 0 && b == 0){
... делай два
} else {
... делай три
}
в принципе можно здесь тоже применить поразрядные операции, но глупо и платформозависимо. наверное это ошибка в условии. человек и имел ввиду логические операции сравнения.
0
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
19.08.2009, 23:15 #7
Цитата Сообщение от novi4ok Посмотреть сообщение
а зачем так сложно?
Задачку до конца дочитайте. Я тоже сперва на выражение посмотрел и долго тупил.
0
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
20.08.2009, 00:36 #8
Цитата Сообщение от skvor Посмотреть сообщение
Задачку до конца дочитайте. Я тоже сперва на выражение посмотрел и долго тупил.
и действительно... заморочка. но что означает "функция принимает целое значение"? мы сейчас можем долго спорить на эту тему, т.к. существует не один способ как это можно истолковать.
кроме того, нигде не стоит, что начальное, конечное значения и интервал - действительные числа (кстати, в реализации отсутствует проверка на то, что начальное значение меньше конечного, что допускает бесконечный, или по крайней мере очень длинный цикл).
пример толкований:
0. если ля-ля-ля равно нулю, исходные данные преобразуются в целые, дальше - все по целочисленной арифметике.
1. если ля-ля-ля равно нулю, конечный результат преобразуется в целое.
2. если ля-ля-ля равно нулю, конечный результат округляется по правилам округления до ближайшего целого.
3. если ля-ля-ля равно нулю, исходные данные округляется по правилам округления до ближайшего целого, дальше - по целочисленной арифметике.
...
0
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
20.08.2009, 00:41 #9
novi4ok, ну, скорее, надо выделять целую часть по "машинным понятиям"
Хотя это не суть, если что - светит замена только одного оператора.
А вот для Aц и других - логичнее именно выделение целой части и работа с ними как с битовыми полями или типа того.
0
M128K145
Эксперт С++
8297 / 3517 / 143
Регистрация: 03.07.2009
Сообщений: 10,706
20.08.2009, 01:01 #10
Цитата Сообщение от skvor Посмотреть сообщение
Плюс, сделали ошибку в теле for - у Вас три оператора if идут последовательно, а должны быть вложены.
Какая разница? Это не ошибка. Ну не выполнилось условие - программа пошла дальше и наткнулась на новое условие, проверила и так далее. Зачем else ставить? Здесь он не нужен.
Цитата Сообщение от skvor Посмотреть сообщение
Кашмар!
Не знаю, будет работать или нет! Но зачёт за такое поставит только урод.
Человек попросил о помощи. Я понимаю, возможно ты знаеш больше чем Biblio, но зто не повод так эмоционально на все ошибки реагировать. Представь, если б на все ошибки которые ты допускаеш так реагировали, тебе бы тоже это не нравилось.
0
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
20.08.2009, 01:07 #11
Цитата Сообщение от M128K145 Посмотреть сообщение
Человек попросил о помощи. Я понимаю, возможно ты знаеш больше чем Biblio, но зто не повод так эмоционально на все ошибки реагировать. Представь, если б на все ошибки которые ты допускаеш так реагировали, тебе бы тоже это не нравилось.
Опять по диагонали читаете - то была потенциальная оценка человека, готового поставить зачёт.
Для меня препод-урод - не тот кто студентов пинает, а тот, кто ставит зачёты не за знания по предмету. И эта оценка преподов не зависит от того, является ли его предмет профильным или общеинженерной ("ненужной") дисциплиной.
0
accept
4825 / 3246 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
20.08.2009, 05:48 #12
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
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
20.08.2009, 06:45 #13
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
accept, попробуйте скомпилировать
cout << (IntParts(a, b, c) ? (long) f : f) << endl;
0
accept
4825 / 3246 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
20.08.2009, 08:18 #14
C++
1
cout << (IntParts((int) a, (int) b, (int) c) ? (long) f : f) << endl;
явное приведение, вообще оно приводит к типам в прототипе
поэтому можно делать free(p); без приведения

Добавлено через 1 час 5 минут 15 секунд
для C++ всё таки обязательно приводить, потому что там бывают перегруженные функции и от типов аргументов зависит какой из вариантов одной функции должен сработать
0
Biblio
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
20.08.2009, 12:21  [ТС] #15
Спасибо всем огромное за комментарии. Если я правильно понимаю, вся загвоздка задачи в этой фразе: "Функция 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
20.08.2009, 12:21
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.08.2009, 12:21
Привет! Вот еще темы с ответами:

Поразрядные операции - C++
Есть 16-е число, например N=0xC5D612F7, помогите убрать единицу в старшем бите у C и F, используя поразрядные операции на языке Си. Я даже...

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

Поразрядные операции - C++
Запрограммировать изменение четырехбайтного числа (unsigned int) так, чтобы байт последовательно заполнялся сначала единицами, а затем...

поразрядные операции - C++
Народ, помогите пожалуйста решить задачу. Задание на скрине. Заранее спасибо.


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru