2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
1

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

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

Author24 — интернет-сервис помощи студентам
Решаю задачу из учебника Павловская, Щупак. С++. Программироание на языке высокого уровня. Структурное программирование. Практикум. Часть 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
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.08.2009, 21:02
Ответы с готовыми решениями:

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

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

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

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

35
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
20.08.2009, 21:50  [ТС] 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от Alexandoros Посмотреть сообщение
Потому что логические и порязрядные операции дают разные результаты. 0xF0 && 0x0F -> true 0xF0 & 0x0F -> false
Спасибо большое.
Но остается главный вопрос: правильно я поняла задачу или нет? А понимаю я ее так:
Требуется 1) вычислить функцию F, 2) вывести ее результаты на экран в зависимости от условия (Ац ИЛИ Вц) И (Ац ИЛИ Сц), которое содержательно никак не связано с самой функцией (дается просто для тренировки).
Что я и сделала. Правда, в моем решении почему-то это выражение всегда не равно нулю. Может такое быть или нет?
0
640KB мне хватило на всё.
119 / 50 / 3
Регистрация: 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
0
556 / 510 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
20.08.2009, 22:43 23
Цитата Сообщение от Biblio Посмотреть сообщение
Спасибо большое.
Но остается главный вопрос: правильно я поняла задачу или нет? А понимаю я ее так:
Требуется 1) вычислить функцию F, 2) вывести ее результаты на экран в зависимости от условия (Ац ИЛИ Вц) И (Ац ИЛИ Сц), которое содержательно никак не связано с самой функцией (дается просто для тренировки).
Что я и сделала. Правда, в моем решении почему-то это выражение всегда не равно нулю. Может такое быть или нет?
Biblio, хочу дать вам дельный совет: не заморачивайтесь с данной задачей: условие у нее дурацкое, высосанное из пальца. в том виде как вы ее решили, вы уже достойны оценки "отлично". мне нравится как вы думаете и соображаете. из вас получится отличный программер, если вы не передумаете и не найдете себе более интересное и полезное применение.
0
Эксперт JavaЭксперт С++
8384 / 3616 / 419
Регистрация: 03.07.2009
Сообщений: 10,709
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;
Обьясни суть этого шага
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
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

единственное, в чем можешь быть уверена, они коммутативны (то есть, от перемены мест слагаемых результат не меняется)
0
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;
Думаю, это чисто стилистические вещи. Сути дела не меняют. Просто для кого-то так удобнее писать, нагляднее.
Всем еще раз большое спасибо.
0
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
21.08.2009, 13:51  [ТС] 27
Ошибка с при переходе через ноль все равно остается. См. скриншот.
Миниатюры
Зачем нужные поразрядные операции. Книга Павловская, Щупак  
0
640KB мне хватило на всё.
119 / 50 / 3
Регистрация: 07.06.2009
Сообщений: 442
21.08.2009, 13:57 28
Biblio, таки последнюю версиию программы в студию!
0
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 - есть ошибка
0
229 / 67 / 11
Регистрация: 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)
0
640KB мне хватило на всё.
119 / 50 / 3
Регистрация: 07.06.2009
Сообщений: 442
21.08.2009, 14:14 31
В задании - x сравнивается с нулём операцией <, а у вас
(fabs(x) < 1e-6 && b != 0)
т.е. x проверяется на равенство нулю.
Вероятно, надо заменить на
(x < -1e-6 && b != 0)
и аналогично дальше.
0
Эксперт С++
7175 / 3234 / 81
Регистрация: 17.06.2009
Сообщений: 14,164
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;
}
0
640KB мне хватило на всё.
119 / 50 / 3
Регистрация: 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;
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
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;
}
не булевые они, в том то и дело
и то, что они так выглядят, идентично - это просто совпадение
0
4866 / 3288 / 468
Регистрация: 10.12.2008
Сообщений: 10,570
23.08.2009, 06:34 35
Цитата Сообщение от Biblio
Относительно разбивки cout << "f (x < 0 && b !=0): " << f << endl;
Думаю, это чисто стилистические вещи. Сути дела не меняют.
ну, это в смысле, лучше читать одну строку (править, заменять, etc), чем десять
0
Эксперт С++
7175 / 3234 / 81
Регистрация: 17.06.2009
Сообщений: 14,164
23.08.2009, 23:05 36
2skvor: ты код сначала посмотри, я специально подравниваю значение x при близких к 0 значениях.
0
23.08.2009, 23:05
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.08.2009, 23:05
Помогаю со студенческими работами здесь

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

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

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

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


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru