Классические алгоритмы и игры на C# для школьников

Арифметические операции, функции и выражения

Разбить на страницы
Показывать лекцию целиком

И снова о числах

Арифметический тип данных является одним из основных типов данных. Встроенными типами, с которыми мы познакомились, являются тип int, задающий некоторое подмножество целых чисел, и тип double, задающий числа, имеющие целую часть, дробную часть и десятичный порядок. Чаще всего, числа рассматриваются как неделимые, хотя мы и видели, что их можно разобрать на цифры, можно найти делители числа и другие его составляющие. Но основой являются операции над числами как неделимыми единицами.

Привычными являются бинарные операции сложения, вычитания, умножения (+, -, *):

A = B + C;

Результаты этих операций интуитивно понятны и соответствуют их пониманию в математике. Следует заметить, что для компьютера сложение целых и сложение вещественных – это разные операции. Когда операция сложения выполняется над двумя операндами, один из которых типа int, а другой – double, то перед сложением тип int преобразуется в тип double. Такое преобразование всегда возможно, поскольку целые числа – это часть вещественных чисел (каждое целое число – это вещественное число, а обратное утверждение неверно).

Понятны и унарные операции (+ и -):

A = -B;

Деление чисел и взятие остатка от деления нацело

Один и тот же знак операции деления чисел (/) означает разные операции. Если оба операнда (делимое и делитель) типа int, то это операция деления нацело и возвращает результат типа int. Если же один из операндов или оба – типа double, то это деление вещественных и результат имеет тип double.

Результат операции взятия остатка от деления нацело (%) интуитивно понятен при делении целых положительных чисел. Для отрицательных и вещественных чисел эта операция хотя и допустима, но применяется редко.

Следует еще отметить особенности деления на нуль. Для целых чисел в результате деления на нуль возникает ошибка, для вещественных чисел ошибки не возникает, но результат равен специальному значению – infinity (бесконечность).

Пример:

int m, n, p, q, r;
            double a, b, c, d;
            m = 2; n = 3; p = m * n; q = n / p; r = n % p;
            a = 2.2; b = 3.3; c = a * b; d = b / c; 
            Console.WriteLine("m = {0} n = {1} " +
                " p = {2} q = {3} r = {4} ", m, n, p, q, r);
            Console.WriteLine("a = {0} b = {1} " +
                " c = {2} d = {3} ", a, b, c, d);
Результаты:
m = 2 n = 3  p = 6 q = 0 r = 3
a = 2,2 b = 3,3  c = 7,26 d = 0,454545454545455

Операции отношения

Операции отношения или сравнения (>, <, >=, <=, ==, !=) определены как над целыми, так и над вещественными числами. Результат этих операций true или false (истина или ложь) имеет тип bool. Эти операции широко применяются при задании условий в операторах выбора и цикла.

Логические операции и операции сдвига

Над целыми числами определены логические операции – конъюнкция, дизъюнкция, исключающее или, отрицание $(\,\; \mid\;,\hat\;,\;\tilde \;)$. Эти операции основаны на том, что целые числа в памяти компьютера записаны в двоичной системе и представляют последовательности нулей и единиц. Если 0 интерпретировать как false, а 1 как true, то можно выполнять логические операции над соответствующими парами битов.

Пример:

            int m = 12; //двоичное представление 1100
            int n = 7;  //двоичное представление 0111
            int p = m  n; //результат 4 - 0100
            Console.WriteLine("m = {0}, n = {1} p = m  n = {2}",
                                m, n, p);

Логические операции над целыми числами с успехом применяются при решении важного класса задач.

Операции сдвига целого числа N влево и вправо на k разрядов (<<, >>) дают тот же эффект, что и умножение (деление) числа N на число 2k. При сдвиге влево на один разряд к числу приписывается 0. В десятичной системе это означало бы умножение на 10, а в двоичной системе – умножение на два. Их применяют по той причине, что сдвиг выполняется быстрее умножения, но без них легко обойтись.

Функции и процедуры – стандартные и определенные программистом

Операций над числами достаточно, чтобы решать самые сложные задачи, связанные с числами. Однако значительно удобнее решать требуемые задачи, если определены различные функции и процедуры, применяемые к числам. Известные математические функции, аргументами которых являются числа, собраны в класс Math (математика), доступный в стандартной библиотеке классов FCL среды разработки – Visual Studio. В этом классе есть такие функции как синус, косинус, логарифм числа и другие полезные функции. Например, функция Pow (сокращение от Power) позволяет число N возводить в степень m. Числа N и m могут быть как целыми, так и вещественными. Поэтому эту функцию можно использовать как для возведения в степень, так и для извлечений корня произвольной степени из числа N. Для частного случая извлечения квадратного корня предлагается специальная функция Sqrt.

Пример:

            double m = Math.Pow(2, 5);
            int n = 1 << 5;
            double p = Math.Pow(20, 1.0 / 4); 
            Console.WriteLine("m = {0}, n = {1} p = m  n = {2}",
                                m, n, p);
Результаты:
m = 32, n = 32 p =  2,11474252688113

При решении конкретной задачи чаще всего приходится создавать собственные функции и процедуры. Напоминаю, наша главная задача научиться программировать в процедурах и функциях. Сложность этой задачи в том, что не так просто понять, какие функции и процедуры следует создать, чтобы эффективно решить требуемую задачу.

Конечно, прежде всего нужно понимать, как синтаксически оформить тот или иной фрагмент кода в виде процедуры или функции. Мы уже создали ряд процедур и функций для решения задачи перевода чисел из одной системы счисления в другую. В игре "Быки и коровы", где требуется работа с цифрами числа, разработана функция Split, разбирающая число N – аргумент функции - на цифры и возвращающая массив, элементами которого являются цифры числа N.

Арифметические выражения

При проведении вычислений не обойтись без оператора присваивания, который позволяет переменной дать новое значение, полученное в результате вычисления значения некоторого выражения. Что же такое выражение в языках программирования?

Выражение также, как и переменная, имеет значение и тип. Арифметическое выражение имеет арифметический тип – int или double. Первичными выражениями являются переменные, константы и функции, - все они имеют значение и тип. Выражением называется последовательность первичных выражений, соединенных знаками операций и скобками.

Чтобы вычислить значение и тип выражения, недостаточно знать, какое значение и какой тип создается при выполнении каждой операции. Необходимо знать порядок выполнения операций при вычислении выражения. Операции в выражении имеют разный приоритет, а операции одного приоритета могут выполняться либо в порядке "слева направо", либо "справа налево". Для арифметических выражений порядок известен из математики. Высшим приоритетом (выполняются первыми) обладают унарные операции, затем операции умножения (*, /, %), затем бинарные операции сложения (+, -). Все упомянутые операции одного приоритета выполняются слева направо. Скобки позволяют изменить порядок выполнения операций. Выражение, заключенное в скобки, получает высший приоритет. В выражении "(a + b) * c" вначале будет выполняться операция сложения, заключенная в скобки, а потом будет выполняться умножение. Без скобок порядок выполнения операций был бы противоположный. Примеры выражений в наших программах встречались неоднократно.

Давайте посмотрим, как строятся выражения на примере решения задач по математике из учебника Виленкина для 6-го класса.

Переходя от содержательной постановки задачи к формализованной, задачу можно сформулировать так. Нужно найти сумму трех переменных:

S = a1 + a2 + a3,

Значение переменной a1 известно, а остальные переменные связаны соотношением:

a2 = a1(* /) k; a3 = a2 + b;

Дано: a1, k, b.

Найти: a2, a3, S.

Постройте программный проект и примените его к решению обоих вариантов задачи 25 и задачи 29.

При вычислении сложных выражений следует максимально использовать локальные переменные. Пример вычисления первого выражения:

static void Vil_697()
        {
            double a = 3.0 / 4;
            a *= 1.8;
            a *= 6.0 / 5;
            a /= 7e-2;

            double b = 1.0 / 5;
            b /= 0.49;
            b *= 21.0 / 8;
            double expr1 = a / b;
            Console.WriteLine("выражение 1 =" + expr1);
        }

Обратите внимание, при делении констант целого типа для получения результата типа double необходимо хотя бы одну константу превратить в константу типа double, представив ее с целой и дробной частью (3.0 / 4).

Задание домой:

Создать программные проекты для решения задач "Виленкин 1590 -1594"

Страницы:

И снова о числах

Арифметический тип данных является одним из основных типов данных. Встроенными типами, с которыми мы познакомились, являются тип int, задающий некоторое подмножество целых чисел, и тип double, задающий числа, имеющие целую часть, дробную часть и десятичный порядок. Чаще всего, числа рассматриваются как неделимые, хотя мы и видели, что их можно разобрать на цифры, можно найти делители числа и другие его составляющие. Но основой являются операции над числами как неделимыми единицами.

Привычными являются бинарные операции сложения, вычитания, умножения (+, -, *):

A = B + C;

Результаты этих операций интуитивно понятны и соответствуют их пониманию в математике. Следует заметить, что для компьютера сложение целых и сложение вещественных – это разные операции. Когда операция сложения выполняется над двумя операндами, один из которых типа int, а другой – double, то перед сложением тип int преобразуется в тип double. Такое преобразование всегда возможно, поскольку целые числа – это часть вещественных чисел (каждое целое число – это вещественное число, а обратное утверждение неверно).

Понятны и унарные операции (+ и -):

A = -B;

Деление чисел и взятие остатка от деления нацело

Один и тот же знак операции деления чисел (/) означает разные операции. Если оба операнда (делимое и делитель) типа int, то это операция деления нацело и возвращает результат типа int. Если же один из операндов или оба – типа double, то это деление вещественных и результат имеет тип double.

Результат операции взятия остатка от деления нацело (%) интуитивно понятен при делении целых положительных чисел. Для отрицательных и вещественных чисел эта операция хотя и допустима, но применяется редко.

Следует еще отметить особенности деления на нуль. Для целых чисел в результате деления на нуль возникает ошибка, для вещественных чисел ошибки не возникает, но результат равен специальному значению – infinity (бесконечность).

Пример:

int m, n, p, q, r;
            double a, b, c, d;
            m = 2; n = 3; p = m * n; q = n / p; r = n % p;
            a = 2.2; b = 3.3; c = a * b; d = b / c; 
            Console.WriteLine("m = {0} n = {1} " +
                " p = {2} q = {3} r = {4} ", m, n, p, q, r);
            Console.WriteLine("a = {0} b = {1} " +
                " c = {2} d = {3} ", a, b, c, d);
Результаты:
m = 2 n = 3  p = 6 q = 0 r = 3
a = 2,2 b = 3,3  c = 7,26 d = 0,454545454545455

Операции отношения

Операции отношения или сравнения (>, <, >=, <=, ==, !=) определены как над целыми, так и над вещественными числами. Результат этих операций true или false (истина или ложь) имеет тип bool. Эти операции широко применяются при задании условий в операторах выбора и цикла.

Логические операции и операции сдвига

Над целыми числами определены логические операции – конъюнкция, дизъюнкция, исключающее или, отрицание $(\,\; \mid\;,\hat\;,\;\tilde \;)$. Эти операции основаны на том, что целые числа в памяти компьютера записаны в двоичной системе и представляют последовательности нулей и единиц. Если 0 интерпретировать как false, а 1 как true, то можно выполнять логические операции над соответствующими парами битов.

Пример:

            int m = 12; //двоичное представление 1100
            int n = 7;  //двоичное представление 0111
            int p = m  n; //результат 4 - 0100
            Console.WriteLine("m = {0}, n = {1} p = m  n = {2}",
                                m, n, p);

Логические операции над целыми числами с успехом применяются при решении важного класса задач.

Операции сдвига целого числа N влево и вправо на k разрядов (<<, >>) дают тот же эффект, что и умножение (деление) числа N на число 2k. При сдвиге влево на один разряд к числу приписывается 0. В десятичной системе это означало бы умножение на 10, а в двоичной системе – умножение на два. Их применяют по той причине, что сдвиг выполняется быстрее умножения, но без них легко обойтись.

Функции и процедуры – стандартные и определенные программистом

Операций над числами достаточно, чтобы решать самые сложные задачи, связанные с числами. Однако значительно удобнее решать требуемые задачи, если определены различные функции и процедуры, применяемые к числам. Известные математические функции, аргументами которых являются числа, собраны в класс Math (математика), доступный в стандартной библиотеке классов FCL среды разработки – Visual Studio. В этом классе есть такие функции как синус, косинус, логарифм числа и другие полезные функции. Например, функция Pow (сокращение от Power) позволяет число N возводить в степень m. Числа N и m могут быть как целыми, так и вещественными. Поэтому эту функцию можно использовать как для возведения в степень, так и для извлечений корня произвольной степени из числа N. Для частного случая извлечения квадратного корня предлагается специальная функция Sqrt.

Пример:

            double m = Math.Pow(2, 5);
            int n = 1 << 5;
            double p = Math.Pow(20, 1.0 / 4); 
            Console.WriteLine("m = {0}, n = {1} p = m  n = {2}",
                                m, n, p);
Результаты:
m = 32, n = 32 p =  2,11474252688113

При решении конкретной задачи чаще всего приходится создавать собственные функции и процедуры. Напоминаю, наша главная задача научиться программировать в процедурах и функциях. Сложность этой задачи в том, что не так просто понять, какие функции и процедуры следует создать, чтобы эффективно решить требуемую задачу.

Конечно, прежде всего нужно понимать, как синтаксически оформить тот или иной фрагмент кода в виде процедуры или функции. Мы уже создали ряд процедур и функций для решения задачи перевода чисел из одной системы счисления в другую. В игре "Быки и коровы", где требуется работа с цифрами числа, разработана функция Split, разбирающая число N – аргумент функции - на цифры и возвращающая массив, элементами которого являются цифры числа N.

Арифметические выражения

При проведении вычислений не обойтись без оператора присваивания, который позволяет переменной дать новое значение, полученное в результате вычисления значения некоторого выражения. Что же такое выражение в языках программирования?

Выражение также, как и переменная, имеет значение и тип. Арифметическое выражение имеет арифметический тип – int или double. Первичными выражениями являются переменные, константы и функции, - все они имеют значение и тип. Выражением называется последовательность первичных выражений, соединенных знаками операций и скобками.

Чтобы вычислить значение и тип выражения, недостаточно знать, какое значение и какой тип создается при выполнении каждой операции. Необходимо знать порядок выполнения операций при вычислении выражения. Операции в выражении имеют разный приоритет, а операции одного приоритета могут выполняться либо в порядке "слева направо", либо "справа налево". Для арифметических выражений порядок известен из математики. Высшим приоритетом (выполняются первыми) обладают унарные операции, затем операции умножения (*, /, %), затем бинарные операции сложения (+, -). Все упомянутые операции одного приоритета выполняются слева направо. Скобки позволяют изменить порядок выполнения операций. Выражение, заключенное в скобки, получает высший приоритет. В выражении "(a + b) * c" вначале будет выполняться операция сложения, заключенная в скобки, а потом будет выполняться умножение. Без скобок порядок выполнения операций был бы противоположный. Примеры выражений в наших программах встречались неоднократно.

Давайте посмотрим, как строятся выражения на примере решения задач по математике из учебника Виленкина для 6-го класса.

Переходя от содержательной постановки задачи к формализованной, задачу можно сформулировать так. Нужно найти сумму трех переменных:

S = a1 + a2 + a3,

Значение переменной a1 известно, а остальные переменные связаны соотношением:

a2 = a1(* /) k; a3 = a2 + b;

Дано: a1, k, b.

Найти: a2, a3, S.

Постройте программный проект и примените его к решению обоих вариантов задачи 25 и задачи 29.

При вычислении сложных выражений следует максимально использовать локальные переменные. Пример вычисления первого выражения:

static void Vil_697()
        {
            double a = 3.0 / 4;
            a *= 1.8;
            a *= 6.0 / 5;
            a /= 7e-2;

            double b = 1.0 / 5;
            b /= 0.49;
            b *= 21.0 / 8;
            double expr1 = a / b;
            Console.WriteLine("выражение 1 =" + expr1);
        }

Обратите внимание, при делении констант целого типа для получения результата типа double необходимо хотя бы одну константу превратить в константу типа double, представив ее с целой и дробной частью (3.0 / 4).

Задание домой:

Создать программные проекты для решения задач "Виленкин 1590 -1594"

Вернуться к учебному плану