Тарифы Услуги Сим-карты

Как найти остаток от деления java. Арифметические операции

1. Основные арифметические операции

В следующей таблице перечислены основные арифметические операции, применяемые в языке Java:

Рассмотрим некоторые правила работы с арифметическими операциями:

  • Выражения вычисляются слева направо, если не добавлены круглые скобки или одни операции имеют более высокий приоритет.
  • Операции *, /, и % имеют более высокий приоритет чем + и -.

Пример 1. Арифметические операции над целочисленными значениями

Например, в этом коде, переменные a и b будут иметь разные значения:

Public class BasicIntMath { public static void main(String args) { int a = 4 + 5 - 2 * 3; int b = 4 + (5 - 2) * 3; System.out.println("a = " + a); System.out.println("b = " + b); } }

Результат выполнения:

A = 3 b = 13

  • Операция унарного вычитания изменяет знак своего единственного операнда.
  • Операция унарного сложения просто возвращает значение своего операнда. Она в принципе не является необходимой, но возможна.

Пример 2. Унарные операции сложения и вычитания

public class UnarySignOperation { public static void main(String args) { double a = -6; double b = +6; System.out.println(a); System.out.println(b); } }
  • Когда операция деления выполняется над целочисленным типом данных, ее результат не будет содержать дробный компонент.

Пример 3. Деление целочисленных чисел

public class IntDivision { public static void main(String args) { int a = 16 / 5; System.out.println(a); } }

Результат выполнения этой программы:

  • Операнды арифметических операций должны иметь числовой тип. Арифметические операции нельзя выполнять над логическими типами данных, но допускается над типами данных char , поскольку в Java этот тип, по существу, является разновидностью типа int .

Пример 4. Арифметические операции над переменными типа char

public class BasicCharMath1 { public static void main(String args) { char c = "n"; System.out.println(c); System.out.println(c + 1); System.out.println(c / 5); } }

Результат выполнения:

N 111 22

Пример 5. Арифметические операции над переменными типа char

public class BasicCharMath2 { public static void main(String args) { char c1 = "1"; char c2 = "\u0031"; char c3 = 49; System.out.println(c1 + c2 + c3); } }

Результат выполнения:

    Оператор деления по модулю — обозначается символом %. Этот оператор возвращает остаток от деления первого числа на второй. При делении целого числа результатом будет тоже целое число.

Пример 6. Деление по модулю

public class DivisionByModule { public static void main(String args) { int a = 6 % 5; double b = 6.2 % 5.0; System.out.println(a); System.out.println(b); } }

Результат выполнения:

1 1.2000000000000002

2. Составные арифметические операции с присваиванием

В Java имеются специальные операции, объединяющие арифметические операции с операцией присваивания. Рассмотрим следующее выражение:

А = а + 4;

B Java эту операцию можно записать следующим образом:

А += 4;

Составные операции с присваиванием позволяют не только уменьшить объем кода, но и позволяют выполнять автоматическое преобразование чего не делают обычные операции.

Пример 5. Составные арифметические операции с присваиванием

public class CompoundOperations { public static void main(String args) { int a = 1; int b = 2; int c = 3; a += 3; b *= 2; c += a * b; System.out.println(a); System.out.println(b); System.out.println(c); } }

Разберемся с одним из подходов к вводу данных из стандартного потока через класс java.util.Scanner . Сделаем это на примере простой задачи с очень полезного сайта e-olimp.com

Задача

Введите из стандартного потока одно число. В предположении, что это положительное двузначное целое число выведите в стандартный поток вывода каждую его цифру отдельно (через пробел). Порядок цифр менять не следует.

Тесты

Никаких специфических случаев в алгоритме не предполагается. Делаем три теста — самое маленькое число допустимого диапазона, самое большое и какое-нибудь значение из середины диапазона.

Вход Выход
10 1 0
99 9 9
54 5 4

Решение

Воспользуемся классом java.util.Scanner, чтобы ввести данные в формате целого числа. И вычислим обе его цифры.

Вывод цифр двухзначного целого числа

Java

class Main{ public static void main (String args) throws java.lang.Exception { java.util.Scanner i = new java.util.Scanner(System.in); int n = i.nextInt(); System.out.println(n / 10 + " " + n % 10); } }

class Main {

public static void main (String args ) throws java . lang . Exception {

java . util . Scanner i = new java . util . Scanner (System . in ) ;

int n = i . nextInt () ;

System . out . println (n / 10 + " " + n % 10 ) ;

Пояснения

  1. Описываем переменную i типа java.util.Scanner и тут же присваиваем ей значение нового объекта этого класса. Конструктор изготавливает объект Scanner ‘а из стандартного потока ввода. Т.е. i становится надстройкой над стандартным потоком ввода. Это позволяет нам прочесть целое число, а не просто читать методом read () по одному байту.
  2. С помощью метода nextInt () читаем последовательность цифр и преобразуем её в целое число. Число запоминаем в переменной n.
  3. n / 10 — число десятков в числе. Десятков будет в десять раз меньше чем само число. Выполняется целочисленное деление — деление нацело.
  4. n % 10 — вычисляем остаток от деления на десять — число единиц — самая правая цифра числа.
  5. n / 10 + » » + n % 10 — вставляем между двумя целыми строку из одного пробела. В этом случае числа также преобразуются в строковое представление и все три строки сливаются — называется конкатенация строк. Так работает со строковыми данными операция «+».

Ускоряем ввод/вывод

При всем удобстве указанного подхода он довольно медленный и иногда задачи не заходят по времени. Значительно ускорить работу можно использовав StreamTokenizer и PrintWriter.
Это увеличит объем кода, но сэкономит время.

Ускорение ввода/вывода

Java

import java.io.*; import java.util.*; class Main { static StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))); static PrintWriter out = new PrintWriter(System.out); static int nextInt() throws IOException { in.nextToken(); return (int)in.nval; } public static void main(String args) throws java.lang.Exception { int n = nextInt(); out.println(n / 10 + " " + n % 10); out.flush(); } }

import java . io . * ;

import java . util . * ;

class Main {

static StreamTokenizer in = new StreamTokenizer (new BufferedReader (new InputStreamReader (System . in ) ) ) ;

static PrintWriter out = new PrintWriter (System . out ) ;

static int nextInt () throws IOException {

Большинство операций над примитивными типами выполняется не с помощью методов, а с помощью специальных символов, называемых знаком операции .

Операция присваивания

Присвоение переменной значения константы, другой переменной или выражения (переменных и/или констант, разделенных знаками операций), называется операцией присваивания и обозначается знаком "= ", например: x = 3 ; y = x; z = x; В Java допустимо многократное использование операции присваивания в одном выражении, например: x1 = x2 = x3 = 0 ; Эта операция выполняется справа налево, т.е. сначала переменной x3 присваивается значение 0 , затем переменной x2 присваивается значение переменной x3 (0), и, наконец, переменной x1 присваивается значение переменной x2 (0). Знаки операций, аргументами которых являются числа, разделяются на две категории: унарные (unary) знаки операций с одним аргументом и бинарные (binary) с двумя аргументами.

Унарные операции

В Java определены следующие унарные операции:
  • унарный минус " - " – меняет знак числа или выражения на противоположный;
  • унарный плюс " + " – не выполняет никаких действий над числом или выражением;
  • побитовое дополнение " ~ " (только для целых) – инвертирует все биты поля числа (меняет 0 на 1 и 1 на 0);
  • инкремент " ++ " (только для целых) – увеличивает значение переменной на 1;
  • декремент " -- " (только для целых) – уменьшает значение переменной на 1.
Примеры унарных операций " + " и " - ": int i = 3 , j, k; j= - i; // j = -3 k = + i; // k = 3 Пример операции побитового дополнения: int a = 15 ; int b; b = ~ a; // b = -16 Числа a и b являются числами типа int , т.е. представляются внутри компьютера как двоичные целые числа со знаком длиной 32 бита, поэтому двоичное представление чисел a и b будет выглядеть следующим образом: a = 00000000 00000000 00000000 00001111 b = 11111111 11111111 11111111 11110000 Как видно из этого представления, все нулевые биты в числе a изменены на единичные биты в числе b , а единичные биты в a изменены на нулевые биты. Десятичным представлением числа b будет –16 . Знаки операции инкремента и декремента могут размещаться как до, так и после переменной. Эти варианты называются соответственно префиксной и постфиксной записью этих операции. Знак операции в префиксной записи возвращает значение своего операнда после вычисления выражения. При постфиксной записи знак операции сначала воз­вращает значение своего операнда и только после этого вычисляет инкремент или декремент, например: int x = 1 , y, z; y = ++ x; z= x++ ; Переменная y будет присвоено значение 2 , поскольку сначала значение x будет увеличено на 1 , а затем результат будет присвоен переменной y . Переменной z будет присвоено значение 1 , поскольку сначала переменной z будет присвоено значение, а затем значение x будет увеличено на 1 . В обоих случаях новое значение переменной x будет равно 2 . Следует отметить, что в Java, в отличие от языка C, операции декремента и инкремента могут применяться и к вещественным переменным (типа float и double). Бинарные знаки операций подразделяются на операции с числовым результатом и операции сравнения, результатом которых является булевское значение.

Арифметические бинарные операции

В Java определены следующие арифметические бинарные операции :
  • сложение " + ";
  • вычитание " - ";
  • умножение " * ";
  • деление " / ";
  • вычисление остатка от деления целых чисел " % " (возвращает остаток от деления первого числа на второе, причем результат будет иметь тот же знак, что и делимое), например, результат операции 5%3 будет равен 2 , а результат операции (-7)%(-4) будет равен -3 . В Java операция может использоваться и для вещественных переменных (типа float или double).
Примеры бинарных арифметических операций: int x = 7 , x1, x2, x3, x4, x5; x1 = x + 10 ; // x1 = 17 x2 = x – 8 ; // x2 = -1 x3 = x2 * x; // x3 = -7 x4 = x/ 4 ; // x4 = 1 (при делении целых чисел // дробная часть отбрасывается) x5 = x% 4 // x5 = 3 (остаток от деления // 7 на 4)

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

  • Побитовые операции рассматривают исходные числовые значения как поля битов и выполняют над ними следующие действия:
  • установка бита в i -ой позиции поля результата в 1 , если оба бита в i -ых позициях операндов равны 1 , или в 0 в противном случае – побитовое И (" & ");
  • установка бита в i -ой позиции поля результата в 1 , если хотя бы один бит в i -ых позициях операндов равен 1 , или в 0 в противном случае – побитовое ИЛИ (" | ");
  • установка бита в i -ой позиции поля результата в 1 , если биты в i -ых позициях операндов не равны друг другу, или в 0 в противном случае – побитовое исключающее ИЛИ (" ^ ");
  • сдвиг влево битов поля первого операнда на количество битов, определяемое вторым операндом (бит знака числа при этом не меняется) – побитовый сдвиг влево с учетом знака " << ";
  • сдвиг вправо битов поля первого операнда на количество битов, определяемое вторым операндом (бит знака числа при этом не меняется) – побитовый сдвиг вправо с учетом знака " >> ";
  • сдвиг вправо битов поля первого операнда на количество битов, определяемое вторым операндом (бит знака числа при этом также сдвигается) – побитовый сдвиг вправо без учета знака " >>> ".
Примеры побитовых операций:
  1. Побитовое И

    int x = 112 ; int y = 94 ; int z; z = x & y; // z=80: 00000000 00000000 00000000 01010000
  2. Побитовое ИЛИ

    int x = 112 ; // x: 00000000 00000000 00000000 01110000 int y = 94 ; // y: 00000000 00000000 00000000 01011110 int z; z = x | y; // z = 126: 00000000 00000000 00000000 01111110
  3. Побитовое исключающее ИЛИ

    int x = 112 ; // x: 00000000 00000000 00000000 01110000 int y = 94 ; // y: 00000000 00000000 00000000 01011110 int z; z = x ^ y; // z = 46: 00000000 00000000 00000000 00101110
  4. Сдвиг влево с учетом знака

    int x = 31 , z; // x: 00000000 00000000 00000000 00011111 z = x << 2 ; // z = 124: 00000000 00000000 00000000 01111100
  5. Сдвиг вправо с учетом знака

    int x = - 17 , z; z = x >> 2 ; // z = -5: 11111111 11111111 11111111 11111011
  6. Сдвиг вправо без учета знака

    int x = - 17 , z; // x: 11111111 11111111 11111111 11101111 z = x >>> 2 ; // z = 1073741819 // z: 00111111 11111111 11111111 11111011

Комбинированные операции

В Java для бинарных арифметических операций можно использовать комбинированные (составные) знаки операций: идентификатор операция = выражение Это эквивалентно следующей операции: идентификатор = идентификатор операция выражение Примеры:
  1. Выражение x += b означает x = x + b .
  2. Выражение x -= b означает x = x - b .
  3. Выражение x *= b означает x = x * b .
  4. Выражение x /= b означает x = x / b .
  5. Выражение x %= b означает x = x % b .
  6. Выражение x &= b означает x = x & b .
  7. Выражение x |= b означает x = x | b .
  8. Выражение x ^= b означает x = x ^ b .
  9. Выражение x <<= b означает x = x << b .
  10. Выражение x >>= b означает x = x >> b .
  11. Выражение x >>>= b означает x = x >>> b .

Операции сравнения

В Java определены следующие операции сравнения:
  • " == " (равно), " != " (не равно),
  • " > " (больше), " >= " (больше или равно),
  • " < " (меньше) " <= " (меньше или равно)
имеют два операнда и возвращают булевское значение, соответствующее результату сравнения (false или true ). Следует обратить внимание, что при сравнении двух величин на равенство в Java, как и в C и в C++, используются символы "== " (два идущих без пробела друг за другом знака равенства), в отличие от оператора присваивания, в котором используется символ "= ". Использование символа " = " при сравнении двух величин либо вызывает ошибку при компиляции, либо приводит к неверному результату. Примеры операций сравнения: boolean isEqual, isNonEqual, isGreater, isGreaterOrEqual, isLess, isLessOrEqual; int x1 = 5 , x2 = 5 , x3 = 3 , x4 = 7 ; isEqual = x1 == x2; // isEqual = true isNonEqual = x1 != x2; // isNonEqual = false isGreater = x1 > x3; // isGreater = true // isGreaterOrEqual = true isGreaterOrEqual = x2 >= x3; isLess = x3 < x1; // isLess = true isLessOrEqual = x1 <= x3; // isLessOrEqual = false

Булевские операции

Булевские операции выполняются над булевскими переменными и их результатом также является значение типа boolean . В Java определены следующие булевские операции:
  • отрицание "!" – замена false на true , или наоборот;
  • операция И "&" – результат равен true , только, если оба операнда равны true , иначе результат – false ;
  • операция ИЛИ " | " – результат равен true , только, если хотя бы один из операндов равен true , иначе результат – false .
  • операция исключающее ИЛИ " ^ " – результат равен true , только, если операнды не равны друг другу, иначе результат – false .
Операции " & ", " | " и " ^ " можно, также как и соответствующие побитовые операции использовать в составных операциях присваивания: " &= ", " |= " и " ^= " Кроме того, к булевским операндам применимы операции " == " (равно) и " != " (не равно). Как видно из определения операций ИЛИ и И, операция ИЛИ приводит к результату true , когда первый операнд равен true , незави­симо от значения второго операнда, а операция И приводит к результату false , когда первый операнд равен false , независимо от значения второго операнда. В Java определены еще две булевские операции: вторые версии булевских операций И и ИЛИ, известные как укороченные (short-circuit) логические операции: укороченное И " && " и укороченное ИЛИ " || ". При использовании этих операций второй операнд вообще не будет вычисляться, что полезно в тех случаях, когда правильное функционирование правого операнда зависит от того, имеет ли левый операнд значение true или false . Примеры булевских операций: boolean isInRange, isValid, isNotValid, isEqual, isNotEqual; int x = 8 ; isInRange = x > 0 && x < 5 ; // isInRange = false isValid = x > 0 || x > 5 ; // isValid = true isNotValid = ! isValid; // isNotValid = false isEqual = isInRange == isValid; // isEqual = false // isNotEqual = true isNotEqual = isInRange != isValid

Условная операция

Условная операция записывается в форме выражение-1?выражение-2:выражение-3 . При этом сначала вычисляется выражение выражение-1 , которое должно дать булевское значение, а затем, если выражение-1 имеет значение true , вычисляется и возвращается выражение-2 как результат выполнения операции, либо (если выражение-1 имеет значение false), вычисляется и, как результат выполнения операции, возвращается выражение-3 . Пример условной операции: x= n> 1 ? 0 : 1 ; Переменной x будет присвоено значение 0 , если n>1 (выражение n>1 имеет значение true) или 1 , если n≤1 (выражение n>1 имеет значение false).

Старшинство операций

Операции в выражениях выполняются слева направо, однако, в соответствии со своим приоритетом. Так операции умножения в выражении y = x + z* 5 ; будет выполнена раньше, чем операция сложения, поскольку приоритет операции умножения выше, чем приоритет операции сложения. Приоритеты операций (в порядке уменьшения приоритета) в Java приведены в табл. 1.
Круглые скобки повышают старшинство операций, которые находятся внутри них. Так, если в приведенное выше выражение вставить скобки: y = (x + z) * 5 ; то сначала будет выполнена операция сложения, а затем операция умножения. Иногда скобки используют просто для того, чтобы сделать выражение более читаемым, например: (x > 1 ) && (x <= 5 ) ;

Преобразование и приведение типов при выполнении операций

В операции присваивания и арифметических выражениях могут использоваться литералы, переменные и выражения разных типов, например: double y; byte x; y = x + 5 ; В этом примере выполняется операция сложения переменной x типа byte и литерала 5 (типа int) и результат присваивается переменной y типа double . В Java, как и в языке C, преобразования типов при вычислении выражений могут выполняться автоматически, либо с помощью оператора приведения типа. Однако правила приведения типов несколько отличаются от правил языка C, и в целом являются более строгими, чем в языке C. При выполнении операции присваивания преобразование типов происходит автоматически, если происходит расширяющее преобразование (widening conversion) и два типа совместимы . Расширяющими преобразованиями являются преобразования byte ®short ®int ®long ®float ®double . Для расширяющих преобразований числовые типы, включая целый и с пла­вающей точкой, являются совместимыми друг с другом. Однако числовые типы не совместимы с типами char и boolean . Типы char и boolean не совмес­тимы также и друг с другом. В языке Java выполняется автоматическое преобразование типов также и при сохранении литеральной целочисленной константы (которая имеет по умолчанию тип int) в перемен­ных типа byte , short или long (однако если литерал имеет значение вне диапазона допустимых значений для данного типа, выдается сообщение об ошибке: возможная потеря точности). Если преобразование является сужающим (narrowing conversion), т. е. выполняется преобразование byte ¬ short ¬ char ¬ int ¬ long ¬ float ¬ double , то такое преобразование может привести к потере точности числа или к его искажению. Поэтому при сужающих преобразованиях при компиляции программы выводится диагностическое сообщение о несовместимости типов и файлы классов не создаются. Такое сообщение будет выдано и при попытке преобразование выражений типа byte или short в переменную типа char . Если все же необходимо выполнить такие преобразования, используется операция приведения (cast) типа, которая имеет следующий формат: (тип-преобразования ) значение , где тип-преобразования определяет тип, в который необходимо преобразовать заданное значение , например, в результате выполнения операторов: byte x = 71 ; char symbol = (char ) x; переменная symbol получит значение " G ". Если значение с плавающей точкой присваивается целому типу, то (если значение с плавающей точкой имеет дробную часть) при явном преобразовании типа происходит также усечение (truncation) числа. Так, в результате выполнения оператора int x = (int ) 77.85 ; переменная x получит значение 77 . Если же присваиваемое значение лежит вне диапазона типа-преобразования , то результатом преобразования будет остаток от деления значения на модуль диапазона присваиваемого типа (для чисел типа byte модуль диапазона будет равен 256 , для short – 65536 , для int – 4294967296 и для long – 18446744073709551616). Например, в результате выполнения оператора byte x = (byte ) 514 ; переменная x получит значение 2 . При преобразовании целых или вещественных чисел в данные типа char , преобразование в символ происходит, если исходное число лежит в диапазоне от 0 до 127, иначе символ получает значение " ? ". При выполнении арифметических и побитовых преобразований все значения byte и short , а также char расширяются до int , (при этом в вычислениях для char используется числовое значение кода символа) затем, если хотя бы один операнд имеет тип long , тип целого выражения расширяется до long . Если один из операндов имеет тип float , то тип полного вы­ражения расширяется до float , а если один из операндов имеет тип double , то тип результата будет double . Так, если объявлены переменные byte a, c; short b; то в выражении a + b* c – 15 L + 1.5F + 1.08 - 10 ; сначала, перед вычислением a + b*c значения переменных будут расширены до int , затем, поскольку константа 15 имеет тип long , перед вычитанием результат вычисления будет увеличен до long . После этого, поскольку литерал 1.5 имеет тип float перед сложением с этим литералом результат вычисления a + b*c – 15L будет расширен до float . Перед выполнением сложения с числом 1.08 результат предыдущих вычислений будет расширен до double (поскольку вещественные константы по умолчанию имеют тип double) и, наконец, перед выполнением последнего сложения литерал 10 (по умолчанию int) будет расширен до double . Таким образом, результат вычисления выражения будет иметь тип double . Автоматические расширения типов (особенно расширения short и byte до int) могут вызывать плохо распознаваемые ошибки во время компиляции. Например, в операторах: byte x = 30 , y = 5 ; x = x + y; перед выполнением сложения значение переменных x и y будет расширено до int , а затем при выполнении попытки присвоения результата вычисления типа int переменной типа byte будет выдано сообщение об ошибке. Чтобы этого избежать надо использовать во втором операторе явное преобразование типов: x = (byte ) (x + y) ; Выражение x + y необходимо заключит в скобки потому, что приоритет операции приведения типа, заключенной в скобки, выше, чем приоритет операции сложения. Кстати, если записать второй оператор в виде: x += y; то сообщения об ошибке не будет. Ссылка на перво