Какого типа будет результат операции 4 2
Перейти к содержимому

Какого типа будет результат операции 4 2

  • автор:

Какого типа будет результат операции 4 2

1. Для чего используется указание типа данных величины?

2. Как описывается тип величины в языке Паскаль?

3. Приведите полный перечень типов данных в Турбо Паскале с примерами величин кaждого типа.

4. Какие типы данных относят к скалярным типам данных?

5. Охарактеризуйте целочисленные типы данных: какие они могут принимать значенш в каких операциях могут принимать участие, сколько места занимают в памяти.

6. Какие типы отношений определены над данными целого типа? Какие стандартны функции определены для целых чисел?

7. Чем отличаются вещественные числа от целых?

9. Какие функции преобразуют вещественный аргумент в целое число? Чем они отличаются?

10. Охарактеризуйте символьный тип данных.

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

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

13. Что такое структурированные типы данных?

14. Почему от программиста требуется знание и правильное применение понятия тождественности и совместимости типов величин? Каковы признаки тождественности и уcловия совместимости типов?

15. Что такое выражение, операция, операнд? Какие операции в языке Паскаль вы знаете?

16. Охарактеризуйте каждую арифметическую операцию.

17. Какие операции называются операциями отношения? В чем заключаются особенности результата операций отношения?

18. Охарактеризуйте каждую логическую операцию.

19. Каковы основные правила для определения старшинства операций?

&nbspменю &nbsp &nbsp &nbsp &nbspвверх

Задания

1. Укажите буквы, символы, составные символы: ^, Y, <>, +, *, R, к, $, !, ы

2. Что в списке можно рассматривать как идентификаторы:

FIO, ФИО, 22222, X, Y, >=, &, $, Summa, _Rezult

3. Укажите идентификаторы, которые проще воспринимаются при чтении, объясните причину:

4. Сколько в следующем списке зарезервированных слов:

X, Program, Y, Summa, МуМопеу, Произведение, Vova, begin, end, if, repeat, Read?

5. В каких случаях надо использовать переменные:

1) если в программе используется какое-то число?

2) если в вычислениях какой-то операнд постоянно меняет свое значение?

3) если операнд в выражении хотя бы один раз меняет значение?

6. Какие утверждения неправильны:

1) 144 —целое число?

2) 125 — шестнадцатеричное целое число?

3) 124.98 — вещественное число?

4) $1FF — шестнадцатеричное число?

5) ‘Адрес’ — целочисленная константа?

6) — 12.3 — отрицательное вещественное число?

7) ‘Сумма’ — строковое значение?

7. Какие числа представлены в форме с плавающей точкой:

165, 10.3Е+02, 1234.678, 3789, 5.7Е0.2, 63.9Е—04

8. Какие из следующих утверждений неправильны:

1) для диапазона 1.. 260 лучше всего подходит тип byte;

2) для диапазона 0.. 75000 лучше всего подходит тип word;

3) для диапазона ‘a’..’z’ лучше всего подходит тип char;

4) для вещественных переменных обычно применяется тип real;

5) значение 32000 входит в тип integer.

9. Какой тип подходит для данных диапазона:

6..90?, — 40..+45?, +10..+65000? , 100,0 .. 10000,0?

10. Какой идентификатор описывает самый широкий диапазон данных?

11. Какие из следующих соотношений неправильны:

3) 2347.6Е —03 = 2.34760;

5) 1200Е+03 = 12000.0.

12. Какие из следующих утверждений неправильны:

1) перед шестнадцатеричными числами записывается знак #;

2) для описания переменных используется слово var;

3) для описания констант используется слово const;

4) имена переменных не обязательно описывать в разделе var;

5) значение константы можно изменять.

13. Какие заголовки программ правильны:

1) program Zarplata?

2) program Сумма?

3) program Summa Nalogov?

4) программа TeachKurs?

5) program 12Kurs2?

6) program SummaElementov?

15. Какой из перечисленных разделов обязателен в программе:

4) раздел begin .. end.?

16. Какие из комментариев неправильны:

2) (* Это тоже комментарий *);

6) (*(* Самый последний вариант *)*).

17. Есть ли причины к невыполнению следующей программы:

18. Для чего используется слово uses ?

1) такого слова нет в языке Турбо Паскаль;

2) это какой-то пользовательский идентификатор;

3) с его помощью подключают стандартные библиотеки;

4) это стандартная константа, равная 3,14;

5) это логическая операция.

19. В разделе процедур и функций описываются только стандартные процедуры ?

1) да, только стандартные;

2) нет, только пользовательские;

3) и стандартные, и пользовательские;

4) такого раздела вообще не может быть в программе.

20. Каков будет результат ее выполнения? Измените программу, чтобы результат равнялся 35.

21. Где ошибка в следующей программе?

Writeln(‘Введите Значение X’);

Writeln(‘X в квадрате=’,Х*Х);

22. Где ошибка в следующей программе?

var X,Y,Сумма:integer; begin

Writeln(‘Введите значение X’);

Writeln (‘Введите значение У);

&nbspпредыдущая&nbsp &nbsp &nbsp &nbsp &nbspменю &nbsp &nbsp &nbsp &nbspвверх &nbsp &nbsp &nbsp &nbsp&nbspследующая

Побитовые операции

Побитовые операции (англ. bitwise operations) — операции, производимые над цепочками битов. Выделяют два типа побитовых операций: логические операции и побитовые сдвиги.

Принцип работы

Логические побитовые операции

Битовые операторы И [math](AND,\ \&)[/math] , ИЛИ [math](OR,\ \mid)[/math] , НЕ [math](NOT,\ \sim)[/math] и исключающее ИЛИ [math](XOR,\ $\textasciicircum$,\ \oplus)[/math] используют те же таблицы истинности, что и их логические эквиваленты.

Побитовое И

Побитовое И используется для выключения битов. Любой бит, установленный в [math]0[/math] , вызывает установку соответствующего бита результата также в [math]0[/math] .

&
11001010
11100010
11000010
Побитовое ИЛИ

Побитовое ИЛИ используется для включения битов. Любой бит, установленный в [math]1[/math] , вызывает установку соответствующего бита результата также в [math]1[/math] .

|
11001010
11100010
11101010
Побитовое НЕ

Побитовое НЕ инвертирует состояние каждого бита исходной переменной.

~
11001010
00110101
Побитовое исключающее ИЛИ

Исключающее ИЛИ устанавливает значение бита результата в [math]1[/math] , если значения в соответствующих битах исходных переменных различны.

^
11001010
11100010
00101000

Побитовые сдвиги

Операторы сдвига [math]\lt \lt [/math] и [math]<\gt \gt >[/math] сдвигают биты в переменной влево или вправо на указанное число. При этом на освободившиеся позиции устанавливаются нули (кроме сдвига вправо отрицательного числа, в этом случае на свободные позиции устанавливаются единицы, так как числа представляются в двоичном дополнительном коде и необходимо поддерживать знаковый бит).

Сдвиг влево может применяться для умножения числа на два, сдвиг вправо — для деления.

x = 7 // 00000111 (7) x = x >> 1 // 00000011 (3) x = x // 00000110 (6) x = x // 11000000 (-64) x = x >> 2 // 11110000 (-16) 

В языке программирования Java существует также оператор беззнакового битового сдвига вправо [math]\gt \gt \gt [/math] . При использовании этого оператора на освободившиеся позиции всегда устанавливаются нули.

x = 7 // 00000111 (7) x = x // 11100000 (-32) x = x >>> 2 // 00111000 (56) 

Применение

Сложные операции

Определение знака числа

Пусть дано число [math]x[/math] . Поскольку при сдвиге вправо на освобождающиеся позиции устанавливается бит знака, знак числа [math]x[/math] можно определить, выполнив сдвиг вправо на всю длину переменной:

int32 getSign(x: int32): if x != 0: mask = 1 else: mask = 0 return mask | (x >> 31) // результатом будет -1, 0, или +1 // для отрицательного, равного нулю и положительного числа x соответственно 

Используя побитовые операции можно также узнать, различны ли знаки двух переменных [math]x[/math] и [math]y[/math] . Если числа имеют различный знак, то результат операции XOR, произведенной над их знаковыми битами, будет единицей. Поэтому неравенство [math](x \oplus y) \lt 0[/math] будет верно в том случае, если числа [math]x[/math] и [math]y[/math] разного знака.

Вычисление модуля числа без использования условного оператора

Пусть дано число [math]x[/math] . Если [math]x[/math] положительно, то [math]mask = 0[/math] , и [math](x + mask) \oplus mask = x[/math] . В случае, если [math]x[/math] отрицательно, [math]mask = -1[/math] . Тогда получается, что мы работаем с числом [math]x[/math] так, как будто оно представлено в коде со сдвигом с тем отличием, что у нас знаковый бит принимает значение [math]1[/math] для отрицательных чисел, а [math]0[/math] — для положительных.

int32 abs1(x: int32): mask = x >> 31 return (x + mask) XOR mask int32 abs2(x: int32): mask = x >> 31 return (x + mask) XOR mask
Нахождение минимума и максимума из двух чисел без использования условного оператора

Этот способ корректен только если можно утверждать, что величина [math](x — y)[/math] лежит между граничными значениями типа int.

Пусть даны числа [math]x[/math] и [math]y[/math] разрядности [math]n[/math] . Тогда если [math]x \lt y[/math] , то [math]((x — y) \gt \gt (n — 1)) = -1[/math] , а если [math]x \geqslant y[/math] , то [math]((x — y) \gt \gt (n — 1)) = 0[/math] . Выражение [math]((x — y) \& ((x — y) \gt \gt (n — 1))[/math] принимает значение [math]0[/math] , если [math]x \geqslant y[/math] , и [math](x — y)[/math] , если [math]x \lt y[/math] .

int32 min(x, y: int32): return y + ((x - y) & ((x - y) >> 31)) int32 max(x, y: int32): return x - ((x - y) & ((x - y) >> 31))
Проверка на то, является ли число степенью двойки

Пусть дано число [math]x[/math] . Тогда, если результатом выражения [math](x\ \&\&\ !(x\ \&\ (x — 1)))[/math] является единица, то число [math]x[/math] — степень двойки.

Правая часть выражения [math](!(x\ \&\ (x — 1)))[/math] будет равна единице, только если число [math]x[/math] равно [math]0[/math] или является степенью двойки. Если число [math]x[/math] является степенью двойки, то в двоичной системе счисления оно представляется следующим образом: [math]1\underbrace_[/math] , где [math]n[/math] — показатель степени. Соответственно, выражение [math](x — 1)[/math] будет иметь вид [math]\underbrace_[/math] , и [math]x\ \&\ (x — 1)[/math] равно [math]0[/math] .

Операция логического И в данном выражении отсекает тот случай, когда [math](x = 0)[/math] и не является степенью двойки, но при этом правая часть [math](!(x\ \&\ (x — 1)))[/math] равна единице.

Нахождение младшего единичного бита

Пусть дано число [math]x[/math] и необходимо узнать его младший единичный бит.

Применим к числу [math]x[/math] побитовое отрицание, чтобы инвертировать значения всех его бит, а затем прибавим к полученному числу единицу. У результата первая часть (до младшего единичного бита) не совпадает с исходным числом [math]x[/math] , а вторая часть совпадает. Применив побитовое И к этим двум числам, получим степень двойки, соответствующую младшему единичному биту исходного числа [math](x\ \&\ (\sim x + 1))[/math] .

К такому же результату можно прийти, если сначала отнять от числа [math]x[/math] единицу, чтобы обнулить его младший единичный бит, а все последующие разряды обратить в [math]1[/math] , затем инвертировать результат и применить побитовое И с исходным числом [math](x\ \&\ \sim (x — 1))[/math] .

Нахождение старшего единичного бита

Пусть дано число [math]x[/math] и необходимо узнать его старший единичный бит.

Рассмотрим некоторое число, представим его как [math]0\dots01b \dots b[/math] , где [math]b[/math] — любое значение бита. Тогда, если совершить битовый сдвиг этого числа вправо на [math]1[/math] и произвести побитовое ИЛИ результата сдвига и исходного числа, мы получим результат [math]0\dots011b \dots b[/math] . Если мы повторим эту последовательность действий над полученным числом, но устроим сдвиг на [math]2[/math] , то получим [math]0\dots01111b \dots b[/math] . При каждой следующей операции будем увеличивать модуль сдвига до следующей степени двойки. После некоторого количества таких операций (зависит от разрядности числа) мы получим число вида [math]0\dots01\dots1[/math] . Тогда результатом выполнения действий [math]x — (x \texttt< \gt \gt >1)[/math] будет число, состоящее только из старшего бита исходного числа.

int32 greatestBit(x: int32): power = 1 for i = 1 [math] \ldots\log_2[/math]: x |= x >> power power return x - (x >> 1)
Циклический сдвиг

Пусть дано число [math]x[/math] и надо совершить циклический сдвиг его битов на величину [math]d[/math] . Желаемый результат можно получить, если объединить числа, полученные при выполнении обычного битового сдвига в желаемую сторону на [math]d[/math] и в противоположном направлении на разность между разрядностью числа и величиной сдвига. Таким образом, мы сможем поменять местами начальную и конечную части числа.

int32 rotateLeft(x, d: int32): return (x >> (32 - d)) int32 rotateRight(x, d: int32): return (x >>> d) | (x 
Подсчет количества единичных битов

Для подсчета количества единичных битов в числе [math]x[/math] можно воспользоваться следующим алгоритмом:

// Для чисел других разрядностей необходимо использовать соответствующие константы. int16 setBitsNumber(x: int16): x = x - ((x >>> 1) & 0x5555) x = (x & 0x3333) + ((x >>> 2) & 0x3333) x = (x + (x >>> 4)) & 0x0F0F return (x * 0x0101) >>> 8

Поскольку [math]5555_[/math] равно [math]01010101 01010101_[/math] , результатом операции [math]x\ \&\ 5555_[/math] является число, в котором все нечетные биты соответствуют нечетным битам числа [math]x[/math] . Аналогично, результатом операции [math](x\ \texttt<\gt \gt \gt >\ 1)\ \&\ 5555_[/math] является число, в котором все нечетные биты соответствуют четным битам [math]x[/math] . Четные биты результата в обоих случаях равны нулю.

Мысленно разобьем двоичную запись нашего числа [math]x[/math] на группы по [math]2[/math] бита. Результатом операции [math]x\ \&\ 5555_ + (x\ \texttt<\gt \gt \gt >\ 1)\ \&\ 5555_[/math] будет такое число, что если разбить его двоичную запись на группы по два бита, значение каждой группы соответствует количеству единичных битов в соответствующей паре битов числа [math]x[/math] .

Аналогично, число [math]3333_[/math] равно [math]00110011 00110011_[/math] и операция [math]x = (x\ \&\ 3333_) + (x\ \texttt<\gt \gt \gt >\ 2\ \&\ 3333_)[/math] , примененная к результату, полученному на первом этапе, выполняет подсчет количества единичных битов в блоках по [math]4[/math] . В свою очередь, число [math]\texttt_[/math] равно [math]00001111 00001111_[/math] и операция [math]x = (x\ \&\ \texttt_) + (x\ \texttt<\gt \gt \gt >\ 4\ \&\ \texttt_)[/math] позволяет подсчитать число единичных бит в блоках по [math]8[/math] .

Теперь необходимо просуммировать числа, записанные в блоках по [math]8[/math] битов, чтобы получить искомую величину. Это можно сделать, домножив результат на [math]0101_[/math] [math](1 00000001_)[/math] . Ответ на задачу будет находиться в первых восьми битах произведения. Выполнив сдвиг вправо на [math]8[/math] (для шестнадцатибитных чисел), мы получим долгожданный ответ.

int16 setBitsNumber(x: int16): x = (x & 0x5555) + ((x >>> 1) & 0x5555) x = (x & 0x3333) + ((x >>> 2) & 0x3333) x = (x & 0x0F0F) + ((x >>> 4) & 0x0F0F) return (x * 0x0101) >>> 8

Заметим, что операция [math]x\ \&\ 55_ + (x\ \texttt<\gt \gt \gt >\ 1)\ \&\ 55_[/math] равносильна операции [math]x - (x\ \texttt<\gt \gt \gt >\ 1)\ \&\ 55_[/math] , в чем легко убедиться, рассмотрев все числа из двух бит.

В свою очередь, операцию [math](x\ \&\ \texttt_) + ((x\ \texttt<\gt \gt \gt >\ 4)\ \&\ \texttt_)[/math] можно заменить на [math](x + (x\ \texttt<\gt \gt \gt >\ 4))\ \&\ \texttt_[/math] . Эта замена не повлияет на результат, так как максимальное значение в любой группе из четырех битов данного числа равно четырем, то есть требует только трех битов для записи, и выполнение суммирования не повлечет за собой переполнения и выхода за пределы четверок.

Таким образом, мы получили код, приведенный в начале раздела.

Разворот битов

Чтобы получить биты числа [math]x[/math] , записанные в обратном порядке, применим следующий алгоритм.

// Для чисел других разрядностей нужны соответствующие константы. int16 reverseBits(x: int16): x = ((x & 0x5555) >> 1) & 0x5555) // Четные и нечетные биты поменялись местами. x = ((x & 0x3333) >> 2) & 0x3333) // Биты "перетасовываются" группами по два. x = ((x & 0x0F0F) >> 4) & 0x0F0F) // Биты "перетасовываются" группами по четыре. x = ((x & 0x00FF) >> 8) & 0x00FF) // Биты "перетасовываются" группами по восемь. return x

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

Применение для решения задач

Работа с битовыми масками

Для работы с подмножествами удобно использовать битовые маски. Применяя побитовые операции легко сделать следующее: найти дополнение [math](\sim mask)[/math] , пересечение [math](mask_1\ \&\ mask_2)[/math] , объединение [math](mask_1 \mid mask_2)[/math] множеств, установить бит по номеру [math](mask \mid (1\ \texttt<\lt \lt >\ x))[/math] , снять бит по номеру [math](mask\ \&\ \sim(1\ \texttt<\lt \lt >\ x))[/math] .

Битовые маски используются, например, при решении некоторых задач [1] динамического программирования.

Алгоритм Флойда

Основная статья: Алгоритм Флойда

Алгоритм Флойда–Уоршелла (англ. the Floyd–Warshall algorithm) — алгоритм для нахождения длин кратчайших путей между всеми парами вершин во взвешенном ориентированном графе. Работает корректно, если в графе нет циклов отрицательной величины, а если же такой цикл есть, позволяет найти хотя бы один такой цикл. Асимптотическая сложность алгоритма [math] \Theta(n^3) [/math] , также требует [math] \Theta(n^2) [/math] памяти.

Дерево Фенвика

Основная статья: Дерево Фенвика

Дерево Фенвика (англ. Binary indexed tree) — структура данных, которая может выполнять следующие операции:

  • изменять значение любого элемента в массиве,
  • выполнять некоторую ассоциативную, коммутативную, обратимую операцию [math] \circ [/math] на отрезке [math] [i, j] [/math] .

Данная структура требует [math] O(n) [/math] памяти, а выполнение каждой операции происходит за [math] O(\log n) [/math] .

Функция, позволяющая делать операции вставки и изменения элемента за [math] O(\log n) [/math] , задается следующей формулой [math] F(i) = (i \And (i + 1)) [/math] . Пусть дан массив [math] A = [a_0, a_1, \ldots, a_][/math] . Деревом Фенвика называется массив [math] T [/math] из [math] n [/math] элементов: [math] T_i = \sum\limits_^ a_k[/math] , где [math] i = 0\ldots n - 1 [/math] и [math] F(i) [/math] — функция, которую мы определили ранее.

См. также

  • Определение булевой функции
  • Сумматор
  • Триггеры

Примечания

Источники информации

  • Онлайн справочник программиста на С и С++
  • Побитовые операторы
  • Bit Twiddling Hacks by Sean Eron Anderson
  • Habrahabr — Алгоритмы поиска старшего бита
  • STP's blog — Counting the number of set bits in an integer

Когда 2 + 2 = «4»

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

Бонусом — функции вывода на консоль для этих языков.

Ошибка компиляции

Самый простое и неинтересное поведение — это ошибка компиляции, происходит во всех строго типизированных языках.

cout  

error: ISO C++ forbids comparison between pointer and integer [-fpermissive]

Если указать флаг -fpermissive то произойдёт сравнение указателя на строку и числа 4 которое скорее всего вернёт 0.

writeln((2 + 2) = "4");

Fatal: illegal character "'"'" ($22)
Сообщение об ошибке довольно непонятное

writeln(2 + 2 = '4');

Error: Incompatible types: got «Char» expected «Int64»
Сообщение об ошибке стало вполне понятным. Спасибо GebekovAS.

Print *, 2 + 2 == "4"

Error: Operands of comparison operator '==' at (1) are INTEGER(4)/CHARACTER(1)

Забавно что в этом тексте нет собственно сообщения о том, что сравнение невозможно, просто констатация факта.

System.out.println((2 + 2) == "4");

error: incomparable types: int and String

В сообщение об ошибке всё хорошо кроме того, что не указана какая операция вызвала ошибку.

Console.WriteLine((2 + 2) == "4");

error CS0019: Operator `==' cannot be applied to operands of type `int' and `string'

fmt.Printf(2 + 2 == "4")

cannot convert «4» to type int
invalid operation: «4» == 2 + 2 (mismatched types string and int)

А тут еще лучше

println!("", 2 + 2 == "4");

error: the trait `core::cmp::PartialEq` is not implemented for the type `_` [E0277]

Логичное, но честно говоря далеко не самое понятное сообщение об ошибке

main = putStrLn (show ((2 + 2) == "4"))

No instance for (Num Char) arising from a use of `+'

Сперва я не понял сообщение, потом немного подумал и понял. Но стал понимать Haskel еще меньше чем раньше.
Решение от Sirikid если всё таки очень хочется сравнить ideone.com/CJifV3

Результат False

Следующие на очереди языки которые позволяют сравнивать число и строку, при этом возвращая false (или что-то похожее), скорее всего из-за несовпадения типов переменных.

printf("%i\n",(2 + 2 == "4"));

результат — 0. Сравнение указателя на строку и числа 4 скорее всего вернёт 0. При этом выводится предупреждение, почти такое же как в C++:

warning: comparison between pointer and integer [enabled by default]

(write (eq "123" 123))
print (2 + 2 == "4")

Какого типа будет результат операции 4/2? это информатика.

Лотарингская

Выбери, какие основные угрозы существуют в Интернете Общение с незнакомыми людьми в чатах или по электронной почте Поиск развлечений (например, игр) в … Интернете Угроза заражения вредоносным программным обеспечением (ПО) Установка нелицензионного программного обеспечения​

які об‘єкти табличного процесора Excel ви знаєте? які їх властивості

Введи оценку (0 - остановить ввод): >>> 5 Введи балл (0 — остановить ввод): >>> 4 Введи балл (0 - остановить ввод): >>> 2 В … веди балл (0 — остановить ввод): >>> 3 Введи балл (0 — остановить ввод): >>> 0 Список оценок: [5, 4, 2, 3] Успеваемость: 75.0

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *