C# 1001 notes
6.51K subscribers
331 photos
9 videos
2 files
314 links
Регулярные короткие заметки по C# и .NET.

Просто о сложном для каждого.

admin - @haarrp
加入频道
Арифметические операции в C#

Во вчерашней заметке мы рассмотрели унарные операции инкремента и декремента.

Сегодняшняя тема достаточно простая, однако, обойти её стороной, на мой взгляд, было бы неправильно. Итак.. бинарные арифметические операции в C#:

🔸 + - сложение двух чисел:

int x = 10;
int z = x + 12; // 22


🔸 - - вычитание двух чисел:

int x = 10;
int z = x - 6; // 4


🔸 * - умножение двух чисел:

int x = 10;
int z = x * 5; // 50


🔸 / - деление двух чисел:

int x = 10;
int z = x / 5; // 2

double a = 10;
double b = 3;
double c = a / b; // 3.33333333


При делении стоит учитывать, что если оба операнда представляют целые числа, то результат также будет округляться до целого числа:

double z = 10 / 4; // 2


Хочу обратить ваше внимание на то, что несмотря на тип переменной double, которой будет присвоено итоговое значение, результат деления будет целочисленным числом ввиду того, что литералы 10 и 4 имеют целочисленный тип int.

Для выхода из этой ситуации необходимо определять литералы или переменные, участвующие в операции, именно как типы double или float:

double z = 10.0 / 4.0; // 2.5


🔸 % - остаток от целочисленного деления:

double x = 10.0;
double z = x % 4.0; // 2


💬 Помните ли вы порядок выполнения операторов? Вот небольшое задание для проверки 😉

#basics
Целочисленное деление и округление в C#

При делении одного целочисленного значения на другое с помощью оператора деления / результат всегда округляется до нуля. Другими словами- обрезается:

int n1 = 7 / 2;       // 3
long n2 = -7 / 2; // -3
short n3 = -11 / -3; // 3


Причину этого поведения я описывал в предыдущей заметке - целочисленные аргументы приводят к целочисленному результату.

При попытке поделить на значение, равное 0, мы получим исключение System.DivideByZeroException в runtime:

int i = 0;
int r = 7 / i; // DivideByZeroException


При попытке поделить на литерал 0 мы получим исключение на этапе компиляции:

int r = 7 / 0; // Division by constant zero


💬 Тем удивительнее оказывается тот факт, что в случае деления числа с плавающей точкой на ноль (1.0 / 0) вышеупомянутое исключение выброшено не будет. Мы просто получим в результате бесконечность (Infinity) 🙂

#basics
Округление чисел с плавающей точкой в C#

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

int n1 = 4.8f;  // Cannot implicitly convert


Поэтому в дело вступает явное приведение:

int n1 = (int)4.8f;


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

Если же мы хотим руководствоваться математическими правилами округления, то с этим нам поможет класс System.Convert:

float f1 = 4.8f;
int n1 = Convert.ToInt32(4.8f); // 5


Но и здесь всё не всегда так гладко 😅 Оказывается, в .NET алгоритм округления (banker's rounding) отличается от привычного нам в тех случаях, когда значения являются пограничными: 0.5, 3.5. В этих случаях округление осуществляется в пользу ближайшего чётного:

int n1 = Convert.ToInt32(8.5f);  // 8
int n2 = Convert.ToInt32(9.5f); // 10


💬 Заинтересованы алгоритмом и причиной подобного решения в .NET? Подробнее почитать об этом вы сможете уже самостоятельно здесь 😉

#basics