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

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

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

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

19.08.2009, 21:02. Просмотров 5265. Ответов 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
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
20.08.2009, 20:12 #16
Цитата Сообщение от Biblio Посмотреть сообщение
В августе зачеты никто не ставит. Есть еще просто интерес
Да-а, а я думал на осень хвост оставили

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

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

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

Потому что логические и порязрядные операции дают разные результаты.
0xF0 && 0x0F -> true
0xF0 & 0x0F -> false
1
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
20.08.2009, 21:25 #20
Цитата Сообщение от Alexandoros Посмотреть сообщение
Потому что логические и порязрядные операции дают разные результаты.
Оператор разыменовывания указателя и вычисление квадратного корня, тоже дают разные результаты.
Мотивы автора уже не определить. Но мысль правильная.
1
Biblio
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
20.08.2009, 21:50  [ТС] #21
Цитата Сообщение от Alexandoros Посмотреть сообщение
Потому что логические и порязрядные операции дают разные результаты. 0xF0 && 0x0F -> true 0xF0 & 0x0F -> false
Спасибо большое.
Но остается главный вопрос: правильно я поняла задачу или нет? А понимаю я ее так:
Требуется 1) вычислить функцию F, 2) вывести ее результаты на экран в зависимости от условия (Ац ИЛИ Вц) И (Ац ИЛИ Сц), которое содержательно никак не связано с самой функцией (дается просто для тренировки).
Что я и сделала. Правда, в моем решении почему-то это выражение всегда не равно нулю. Может такое быть или нет?
0
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
0
novi4ok
551 / 504 / 8
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
20.08.2009, 22:43 #23
Цитата Сообщение от Biblio Посмотреть сообщение
Спасибо большое.
Но остается главный вопрос: правильно я поняла задачу или нет? А понимаю я ее так:
Требуется 1) вычислить функцию F, 2) вывести ее результаты на экран в зависимости от условия (Ац ИЛИ Вц) И (Ац ИЛИ Сц), которое содержательно никак не связано с самой функцией (дается просто для тренировки).
Что я и сделала. Правда, в моем решении почему-то это выражение всегда не равно нулю. Может такое быть или нет?
Biblio, хочу дать вам дельный совет: не заморачивайтесь с данной задачей: условие у нее дурацкое, высосанное из пальца. в том виде как вы ее решили, вы уже достойны оценки "отлично". мне нравится как вы думаете и соображаете. из вас получится отличный программер, если вы не передумаете и не найдете себе более интересное и полезное применение.
0
M128K145
Эксперт С++
8297 / 3517 / 143
Регистрация: 03.07.2009
Сообщений: 10,706
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
accept
4825 / 3246 / 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

единственное, в чем можешь быть уверена, они коммутативны (то есть, от перемены мест слагаемых результат не меняется)
0
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;
Думаю, это чисто стилистические вещи. Сути дела не меняют. Просто для кого-то так удобнее писать, нагляднее.
Всем еще раз большое спасибо.
0
Biblio
2 / 2 / 0
Регистрация: 30.04.2009
Сообщений: 27
21.08.2009, 13:51  [ТС] #27
Ошибка с при переходе через ноль все равно остается. См. скриншот.
0
Миниатюры
Зачем нужные поразрядные операции. Книга Павловская, Щупак  
skvor
640KB мне хватило на всё.
118 / 49 / 2
Регистрация: 07.06.2009
Сообщений: 442
21.08.2009, 13:57 #28
Biblio, таки последнюю версиию программы в студию!
0
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 - есть ошибка
0
Alexandoros
228 / 66 / 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)
0
21.08.2009, 14:09
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.08.2009, 14:09
Привет! Вот еще темы с ответами:

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

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

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

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


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

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

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