1. Дробные числа
Давайте вспомним наш проект — допустим, это простейший калькулятор. Или любая программа, где нужны вычисления (от банального подсчёта денег до сложной физики). Далеко не всё в реальной жизни — целое число, и с этим ничего не поделаешь!
Так что давайте вооружимся новым типом данных!
В программировании дробные числа еще называют вещественными, или числами с плавающей точкой (floating-point). В C#, как и в большинстве языков, они нужны для хранения не только целых, но и "дробных" значений: всяких 3.14, -28.57, 2.718281828...
Вещественные числа бывают двух основных типов:
| Тип | Хранит | Диапазон значений (приблизительно) | Точность | Типичный размер |
|---|---|---|---|---|
|
Числа | ±1.5 × 10-45 ... ±3.4 × 1038 | ~7 знаков после запятой | 4 байта |
|
Числа | ±5.0 × 10-324 ... ±1.7 × 10308 | ~15-16 знаков после запятой | 8 байт |
Тип float
Тип float получил название от floating-point number — число с плавающей запятой. Вещественные числа — это числа из математики, у них есть определенные свойства. А у компьютера много ограничений. Поэтому не совсем корректно называть дробные числа в C# вещественными. Для них используется название "числа с плавающей запятой".
Тип float обычно хранит 7 значащих цифр (например 0.1234567), степень десятки и занимает 4 байта в памяти. Этого очень мало для точных вычислений, поэтому все быстро перешли на числа двойной точности.
2. Объявление и инициализация переменных типа double
Всё, как с int — только теперь используем double.
// Объявляем переменную и присваиваем ей значение Пи
double pi = 3.1415926;
// Можно объявить и без инициализации
double averageSalary;
averageSalary = 91234.56;
// Можно вычислять!
double pizzaPieces = 8;
double friends = 3;
double piecesPerFriend = pizzaPieces / friends; // 2.666... (а не 2)
Особенности синтаксиса:
- В качестве десятичного разделителя используется точка (3.14). Если используете запятую — получите ошибку компиляции!
- Строго говоря, записав double d = 3;, вы не получите ошибку — типы автоматически приведутся (целое число превращается во "вещестенное" без потерь).
3. Ввод и вывод вещественных чисел с помощью Console
Сначала попробуем вывести дробное число:
double amount = 42.75;
Console.WriteLine(amount); // Выведет: 42.75
Всё хорошо! А если добавить текст:
Console.WriteLine("На вашем счету: " + amount + " евро."); // На вашем счету: 42.75 евро.
Ввод с клавиатуры
Главная тонкость: Console.ReadLine() всегда возвращает строку, нужно преобразовать её к типу double.
Console.WriteLine("Введите температуру за окном:");
string input = Console.ReadLine();
double temperature = double.Parse(input); // Преобразуем строку в double
Console.WriteLine("На улице сейчас: " + temperature + " градусов.");
4. Тип double в действии: арифметика
Все привычные операции (+, -, *, /) работают, как и для int:
double distance = 100.5;
double time = 2.0;
double speed = distance / time; // 50.25
Console.WriteLine("Средняя скорость: " + speed); // Средняя скорость: 50.25
Вот и вся арифметика. Единственное отличие: результат деления — всегда дробное число, если хотя бы один из операндов — double.
Сравним с int
int a = 5, b = 2;
Console.WriteLine(a / b); // 2 (остаток отбрасывается)
double aa = 5, bb = 2;
Console.WriteLine(aa / bb); // 2.5
5. Типичные ошибки и странности при работе с double
Ошибка преобразования строки
Ситуация классическая: пользователь вводит 3,14 — а программа ждёт 3.14.
// Это вызовет ошибку, если введено "3,14"
double value = double.Parse(Console.ReadLine());
Если работать с программой в странах, где "запятая" — разделитель целой и дробной частей (например, Польша, Германия), то double.Parse отрабатывает нормально. Но если приложение запущено с "английскими" настройками, ждите точку.
Ошибка "неточности" чисел в компьютере
Вот здесь у новичков обычно начинается лёгкое недоумение:
double x = 0.1 + 0.2;
Console.WriteLine(x); // Хм... 0.30000000000000004
Поздравляю, вы столкнулись с "магией" представления дробных чисел внутри компьютера. Дело в том, что многие числа невозможно точно представить в двоичной системе. Подробнее поговорим об этом на следующей лекции, сейчас — не паникуйте! Это обычно некритично для большинства приложений, но есть нюансы в финансах и точных науках.
6. Важно: double и int — автоматическое и явное преобразование
Бывает, что вы складываете целое и дробное, или присваиваете int переменной double, — ошибок не будет:
int i = 2;
double d = i; // Всё ок!
Console.WriteLine(d); // 2
double dd = 3.7;
int ii = (int) dd; // Нужно явно привести тип double к типу int!
Console.WriteLine(ii); // 3, дробная часть отбросилась
Часто это вызывает неожиданность — почему после приведения дробная часть исчезла? Просто потому, что тип int не умеет хранить дроби (всё, что после точки, исчезло навсегда).
Подробнее про преобразование double в int и оператор (int) в следующей лекции.
7. Форматированный вывод: красиво выводим double
Часто по умолчанию double выводится с кучей лишних нулей. Можно отформатировать вывод:
double temp = 23.56789;
Console.WriteLine(temp); // 23.56789
Console.WriteLine(temp.ToString("F2")); // 23.57 (2 знака после запятой)
Console.WriteLine($"{temp:F1}"); // 23.6 (интерполяция строк)
| Формат | Результат | Описание |
|---|---|---|
| "F0" | 24 | Без десятичной части |
| "F2" | 23.57 | Два знака после запятой |
| "F5" | 23.56789 | Пять знаков после запятой |
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ