Форум программистов, компьютерный форум CyberForum.ru

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 41, средняя оценка - 4.90
Biblio
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
19.08.2009, 21:02     Зачем нужные поразрядные операции. Книга Павловская, Щупак #1
Решаю задачу из учебника Павловская, Щупак. С++. Программироание на языке высокого уровня. Структурное программирование. Практикум. Часть 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;
}
Заранее спасибо.
Миниатюры
Зачем нужные поразрядные операции. Книга Павловская, Щупак  
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.08.2009, 21:02     Зачем нужные поразрядные операции. Книга Павловская, Щупак
Посмотрите здесь:

Поразрядные операции C++
C++ Поразрядные операции, объясните смысл выражений
Поразрядные операции C++
поразрядные операции C++
поразрядные операции C++
C++ Поразрядные операции
C++ Поразрядные операции
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Biblio
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
20.08.2009, 21:50  [ТС]     Зачем нужные поразрядные операции. Книга Павловская, Щупак #21
Цитата Сообщение от Alexandoros Посмотреть сообщение
Потому что логические и порязрядные операции дают разные результаты. 0xF0 && 0x0F -> true 0xF0 & 0x0F -> false
Спасибо большое.
Но остается главный вопрос: правильно я поняла задачу или нет? А понимаю я ее так:
Требуется 1) вычислить функцию F, 2) вывести ее результаты на экран в зависимости от условия (Ац ИЛИ Вц) И (Ац ИЛИ Сц), которое содержательно никак не связано с самой функцией (дается просто для тренировки).
Что я и сделала. Правда, в моем решении почему-то это выражение всегда не равно нулю. Может такое быть или нет?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
20.08.2009, 22:29     Зачем нужные поразрядные операции. Книга Павловская, Щупак #22
1) срочно забыть про
Т.е. if(x > 0 && b == 0) можно заменить на if(x > 0 && b) и переставить ветви then-else
Аналогично (x < 0 && b != 0) тождественно (x < 0 && b)
сидиотничал, сори

2) При сравнении вещественных чисел с нулём, лучше вычислять модуль и сравнивать с некоторой константой, которая очень мала, но заведомо больше всяких арифметических ошибок
C++
1
if (fabs(n)<1.0e-7) ... //Считаем n==0
novi4ok
549 / 502 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
20.08.2009, 22:43     Зачем нужные поразрядные операции. Книга Павловская, Щупак #23
Цитата Сообщение от Biblio Посмотреть сообщение
Спасибо большое.
Но остается главный вопрос: правильно я поняла задачу или нет? А понимаю я ее так:
Требуется 1) вычислить функцию F, 2) вывести ее результаты на экран в зависимости от условия (Ац ИЛИ Вц) И (Ац ИЛИ Сц), которое содержательно никак не связано с самой функцией (дается просто для тренировки).
Что я и сделала. Правда, в моем решении почему-то это выражение всегда не равно нулю. Может такое быть или нет?
Biblio, хочу дать вам дельный совет: не заморачивайтесь с данной задачей: условие у нее дурацкое, высосанное из пальца. в том виде как вы ее решили, вы уже достойны оценки "отлично". мне нравится как вы думаете и соображаете. из вас получится отличный программер, если вы не передумаете и не найдете себе более интересное и полезное применение.
M128K145
Эксперт C++
 Аватар для M128K145
8276 / 3495 / 142
Регистрация: 03.07.2009
Сообщений: 10,707
21.08.2009, 00:30     Зачем нужные поразрядные операции. Книга Павловская, Щупак #24
Цитата Сообщение от accept Посмотреть сообщение
C++
1
cout << "f (x < 0 && b !=0): " << f << endl;
это нужно разделить

C++
1
cout << "f (x < 0 && b !=0): ";
C++
1
cout << f << endl;
Обьясни суть этого шага
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
21.08.2009, 04:17     Зачем нужные поразрядные операции. Книга Павловская, Щупак #25
Цитата Сообщение от M128K145
Обьясни суть этого шага
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
 
#include <iostream>
 
using namespace std;
 
int main(void)
{
    float f;
    string mess;
    
    f = 0.5;
    
    if (f > 1.0)
        mess = "one";
    else if (f < 0.4)
        mess = "two";
    else if (f > 0.7)
        mess = "three";
    else
        mess = "four";    
    
    // это потом расходится по функциям (то есть тоже разделяется)
    cout << mess
         << ": "
         << f
         << endl;
    
    return 0;
}
Добавлено через 13 минут 40 секунд
Цитата Сообщение от Biblio
т.е. фактически в нем вычисляется булево выражение (A&B)|(A&C) которое проверяется на равенство нулю.
ты путаешь & и && - это совсем разные операции, & работает наподобие сложения, а по свойствам её называют умножением (так как она обнуляет биты при любом раскладе 0 0 , 0 1, 1 0 ), то есть операция + даёт сумму, а операция & даёт свой результат и он совсем не логический

1 & 2 равно 0

2 & 3 равно 2

-1 & -1 равно -1

а суммой называют |, потому что она по свойствам похожа на сумму и даёт еденицу при любом раскладе 1 1, 1 0, 0 1

3 | 2 равно 3

1 | 2 равно 3

-1 | -1 равно -1

единственное, в чем можешь быть уверена, они коммутативны (то есть, от перемены мест слагаемых результат не меняется)
Biblio
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
21.08.2009, 11:13  [ТС]     Зачем нужные поразрядные операции. Книга Павловская, Щупак #26
Цитата Сообщение от accept Посмотреть сообщение
Добавлено через 13 минут 40 секунд
ты путаешь & и && - это совсем разные операции, & работает наподобие сложения, а по свойствам её называют умножением (так как она обнуляет биты при любом раскладе 0 0 , 0 1, 1 0 ), то есть операция + даёт сумму, а операция & даёт свой результат и он совсем не логический
1 & 2 равно 0
2 & 3 равно 2
-1 & -1 равно -1
а суммой называют |, потому что она по свойствам похожа на сумму и даёт еденицу при любом раскладе 1 1, 1 0, 0 1

3 | 2 равно 3

1 | 2 равно 3

-1 | -1 равно -1

единственное, в чем можешь быть уверена, они коммутативны (то есть, от перемены мест слагаемых результат не меняется)
Мне кажется, как раз не путаю. В булевой алгебре для конъюнкции используется &, и в С++ & есть поразрядная конъюнкция (та что оперирует с битами, т.е. 0 и 1). Но ведь и в булевой алгебре при вычислении выражений используется 0 и 1. В этом смысле я имела ввиду, что выражение типа (А&С)|(А&В) есть фактически переход к решению булевых выражений. Начинаю подозревать, что именно поэтому в С++, который работает на разных уровнях (и с битами, и с человекопонятными объектами) понадобилось сохранить знак & (для работы с битами, читай булевыми выражениями), и еще ввести &&, чтобы устанавливать логические отношения между объектами более высокого уровня, т.е. числами и т.п. Это так, оффтоп.
Думаю, что на этом можно задачу закрыть. Видимо, только сам автор задачи знает, зачем было введено дополнительное условие с поразрядными операциями. В любом случае - я потренировалась и кое-что для себя узнала
Для novi4ok Во-первых спасибо за добрые слова. Они, как известно, и кошке приятны . Во-вторых, условие задачи смутное, верно. Но достоинство учебника в том, что там сразу дается много однотипных задач. А это важно, чтобы "руку набить". Многие учебники содержат по одной задачке на каждую тему, поэтому потом все выветривается моментально. К тому же можно решать только первую часть, т.е. вычисление функций с определенными условиями, а вторую оставить в покое.
Цитата Сообщение от skvor Посмотреть сообщение
2) При сравнении вещественных чисел с нулём, лучше вычислять модуль и сравнивать с некоторой константой, которая очень мала, но заведомо больше всяких арифметических ошибок
C++
1
if (fabs(n)<1.0e-7) ... //Считаем n==0
Спасибо, как раз в книжке той же Павловской нашла похожий совет.

Относительно разбивки cout << "f (x < 0 && b !=0): " << f << endl;
Думаю, это чисто стилистические вещи. Сути дела не меняют. Просто для кого-то так удобнее писать, нагляднее.
Всем еще раз большое спасибо.
Biblio
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
21.08.2009, 13:51  [ТС]     Зачем нужные поразрядные операции. Книга Павловская, Щупак #27
Ошибка с при переходе через ноль все равно остается. См. скриншот.
Миниатюры
Зачем нужные поразрядные операции. Книга Павловская, Щупак  
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
21.08.2009, 13:57     Зачем нужные поразрядные операции. Книга Павловская, Щупак #28
Biblio, таки последнюю версиию программы в студию!
Biblio
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
21.08.2009, 14:05  [ТС]     Зачем нужные поразрядные операции. Книга Павловская, Щупак #29
Простите, упустила.
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
#include <iostream>
#include <cmath>
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 << "Nepravilno. Xk ne mojet bit < 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(fabs(x) < 1e-6 && b != 0)
        {   
            f = a*x*x+b;
            cout << "При х = " << x << "; f (x < 0 && b !=0) = " << f << endl;
        }
        else
        {
            if(fabs(x) > 1e-6 && 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;
}
При значениях -3 2 0.5 - ошибки нет
При значениях -3 5 0.2 - есть ошибка
Alexandoros
226 / 64 / 4
Регистрация: 02.06.2009
Сообщений: 280
21.08.2009, 14:09     Зачем нужные поразрядные операции. Книга Павловская, Щупак #30
Тут легче переписать, чем разбиратся правильно ли написано
Сравнивай

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
int err = 0;
 
for(xtekushiy = xbegin; xtekushiy <= xend; xtekushiy += dx)
{
   
   if( (x < 0) && b)
       f = a*x*x + b;
   else if( (x > 0) && !b)
   {
       if(fabs(x - c) > 1e-30)
           f = (x - a) / (x - c)
       else
       {
           printf("x = %G  f = div by zero\r\n", xtekushiy);
           err = -1;
        }
   }
   else if(c)
       f = x / c;
   else
   {
      printf("x = %G  f = div by zero\r\n", xtekushiy);
      err = -1;
   }    
 
 
   if(!err)
   {
        if(  ((int)a | (int)b) & ( (int) a | (int)c)  )
            printf(" x =  %G     y = %G\r\n", xtekushiy , f);
        else
            printf(" x =  %G     y = %d\r\n", xtekushiy , (int)f);
 
         err = 0;
   }
 
 
 
} //for(xtekushiy = xbegin; xtekushiy <= xend; xtekushiy += dx)
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
21.08.2009, 14:14     Зачем нужные поразрядные операции. Книга Павловская, Щупак #31
В задании - x сравнивается с нулём операцией <, а у вас
(fabs(x) < 1e-6 && b != 0)
т.е. x проверяется на равенство нулю.
Вероятно, надо заменить на
(x < -1e-6 && b != 0)
и аналогично дальше.
odip
Эксперт C++
 Аватар для odip
7226 / 3288 / 59
Регистрация: 17.06.2009
Сообщений: 14,165
21.08.2009, 23:35     Зачем нужные поразрядные операции. Книга Павловская, Щупак #32
Нужно сравнивать как написано - без всяких fabs(XXX)<1e-6
if ( x<0 && b!=0 )
if ( x>0 && b==0 )

Добавлено через 23 секунды
В данном конкретном случае разумеется.

Добавлено через 5 минут 17 секунд
И вообще Alexandoros в посте #30 все уже написал.

Добавлено через 22 минуты 20 секунд
Цикл нужно перебирать немного не так - до конечного значения не всегда удается дойти. А так как значение X очень важно для формулы, то предлагаю делать вот так. Заодно это хороший пример как реально представляются значения.
И лучше использовать double, а не float.
Сравнение 0.0==0 компьютер сделает правильно.
Как и сравнения x<0, x>0.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
#define EPSILON 1.0e-10
 
int main( void ) {
 
double Xn= -3.0, Xk= 5.0, dX= 0.2;
double i_x, x;
 
 
for ( i_x= Xn; i_x<=Xk+EPSILON; i_x+= dX ) {
    x= i_x;
    if ( fabs(x)<EPSILON ) { x= 0.0; }
    printf( "x=%+.30f\n", x );
}
 
return 0;
}
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
22.08.2009, 03:13     Зачем нужные поразрядные операции. Книга Павловская, Щупак #33
Цитата Сообщение от odip Посмотреть сообщение
Сравнение 0.0==0 компьютер сделает правильно.
Сравнение компьютер делает правильно, вот только получить при вычислениях вещественный ноль тяжело.
Скомпилируйте и запустите
C++
1
2
3
4
float a=0.9,b=0.1;
int   c=9,  d=1;
std::cout<<(a+b==1)<<std::endl;
std::cout<<(c+d==10)<<std::endl;
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
23.08.2009, 06:31     Зачем нужные поразрядные операции. Книга Павловская, Щупак #34
там всё таки не одно и то же
&1 и !=0
потому что с чётной a
будет получаться ложь

C
1
2
3
4
5
6
int IntParts(int a, int b, int c)
{
    /* (a || b) && (a || c) */
 
    return ((a | b) & (a | c)) != 0;
}
не булевые они, в том то и дело
и то, что они так выглядят, идентично - это просто совпадение
accept
4838 / 3237 / 165
Регистрация: 10.12.2008
Сообщений: 10,682
23.08.2009, 06:34     Зачем нужные поразрядные операции. Книга Павловская, Щупак #35
Цитата Сообщение от Biblio
Относительно разбивки cout << "f (x < 0 && b !=0): " << f << endl;
Думаю, это чисто стилистические вещи. Сути дела не меняют.
ну, это в смысле, лучше читать одну строку (править, заменять, etc), чем десять
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.08.2009, 23:05     Зачем нужные поразрядные операции. Книга Павловская, Щупак
Еще ссылки по теме:

C++ Правильно ли я написал программу? Из книжки Павловская Щупак
C++ Поразрядные операции (&,|,^)
C++ Поразрядные операции
Поразрядные операции C++
Поразрядные операции C++

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

Или воспользуйтесь поиском по форуму:
odip
Эксперт C++
 Аватар для odip
7226 / 3288 / 59
Регистрация: 17.06.2009
Сообщений: 14,165
23.08.2009, 23:05     Зачем нужные поразрядные операции. Книга Павловская, Щупак #36
2skvor: ты код сначала посмотри, я специально подравниваю значение x при близких к 0 значениях.
Yandex
Объявления
23.08.2009, 23:05     Зачем нужные поразрядные операции. Книга Павловская, Щупак
Ответ Создать тему
Опции темы

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