Decimal vs Double в C#: что выбрать и когда? Гайд 2025

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Decimal vs Double в C#: Битва за точность (и ваши нервы)

Вы когда-нибудь писали калькулятор зарплаты или, скажем, симулятор полета мяча, и вдруг получали 0.30000000000000004 вместо ожидаемых 0.3? Если да — добро пожаловать в клуб. Вопрос "decimal vs double! - Which one should I use and when?" — один из самых популярных на Stack Overflow, и не зря. Кажется, что это просто выбор между двумя типами чисел с плавающей точкой. Но на самом деле это выбор между финансовой катастрофой и научной точностью (или наоборот).

В этой статье мы разберем этот вечный спор раз и навсегда. Вы узнаете, чем тип decimal в C# отличается от типа double, где какой применять и, самое главное, — как не облажаться в 2025 году. Поехали!

Коротко о главном: что скрывается под капотом?

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

Double (он же System.Double)

  • Размер: 64 бита (8 байт).
  • Точность: Примерно 15-17 значащих цифр.
  • Диапазон: Огромный (от ±5.0 × 10−324 до ±1.7 × 10308).
  • Представление: С плавающей точкой по стандарту IEEE 754 (двоичное).
  • Производительность: Высокая. Процессоры оптимизированы для работы с double.

Decimal (он же System.Decimal)

  • Размер: 128 бит (16 байт).
  • Точность: 28-29 значащих цифр.
  • Диапазон: Меньше (от ±1.0 × 10−28 до ±7.9 × 1028).
  • Представление: Десятичное (по сути, целое число со сдвигом запятой).
  • Производительность: Ниже. Нет аппаратной поддержки на CPU, все вычисления — программные.

Главное отличие, которое нужно запомнить: double — это двоичная дробь, а decimal — десятичная. Именно из-за этого возникают знаменитые "ошибки округления".

Почему double "ломает" деньги, но идеален для науки?

Представьте, что вы пытаетесь записать число 0.1 в двоичной системе. Это будет бесконечная периодическая дробь: 0.0001100110011.... Компьютер обрезает её, и получается маленькая, но критичная погрешность. Для научных расчетов (симуляции погоды, физика, графика) эта погрешность накапливается, но в пределах допустимой нормы. Для финансов — это "украденная" копейка у миллиона пользователей.

Decimal же хранит число как целое (например, 1/10 = 0.1 хранится как целое число 1 и информация о том, что запятую нужно сдвинуть на один знак). Поэтому точность decimal идеальна для десятичных дробей.

Когда использовать decimal в C#? (Спойлер: для денег)

Золотое правило, которое спасет ваш проект: используйте decimal для финансовых, денежных и бухгалтерских расчетов. Если в вашей переменной лежат рубли, доллары, проценты по кредиту или НДС — ваш выбор однозначен.

Вот пример, почему double — зло для кошелька:

using System;

public class MoneyExample
{
    public static void Main()
    {
        // Плохой пример с double
        double price = 10.99;
        double tax = 0.07;
        double totalDouble = price + (price * tax);
        Console.WriteLine($"Double total: {totalDouble}"); // Может выдать 11.759300000000001

        // Хороший пример с decimal
        decimal priceDec = 10.99m;
        decimal taxDec = 0.07m;
        decimal totalDec = priceDec + (priceDec * taxDec);
        Console.WriteLine($"Decimal total: {totalDec}"); // Точно: 11.7593
    }
}

Видите эту "лишнюю единицу" в конце у double? В масштабах банковской транзакции это приведет к ошибке сверки баланса. Тип decimal в C# гарантирует, что 0.1 + 0.2 будет строго равно 0.3.

Когда decimal — не лучший выбор:

  • Производительность критична. Если вам нужно обсчитать миллиард значений в секунду (например, в играх или машинном обучении), decimal будет тормозить в 10-20 раз медленнее double.
  • Большие числа. Диапазон decimal ограничен. Для астрономических расчетов (расстояние до звезд) double незаменим.

Когда использовать double в C#? (Наука, графика и скорость)

Double — это "рабочая лошадка" для математики, физики, 3D-графики и статистики. Он быстрый, легкий и имеет огромный диапазон. Если вам не нужна абсолютная точность до 28 знака после запятой — смело берите double.

Пример: рассчет траектории снаряда.

using System;

public class PhysicsExample
{
    public static void Main()
    {
        // Идеально для double
        double velocity = 150.5; // м/с
        double angle = 45.0; // градусы
        double g = 9.81; // ускорение свободного падения

        double radians = angle * Math.PI / 180.0;
        double maxHeight = (velocity * velocity * Math.Sin(radians) * Math.Sin(radians)) / (2 * g);
        Console.WriteLine($"Max height: {maxHeight} meters");

        // Здесь decimal не нужен, так как погрешность в 0.0001 мм нас не волнует.
    }
}

Тип double в C# отлично подходит для:

  • Научных и инженерных расчетов.
  • Обработки изображений и звука.
  • Игровой физики (Vector3, матрицы трансформаций).
  • Хранения больших массивов данных (экономия памяти).

Лучшие практики для C# в 2025 году: чек-лист

Чтобы вы больше никогда не гадали, запомните эту шпаргалку. Это лучшие практики C# 2025, основанные на реальном опыте разработчиков со Stack Overflow.

1. Финансы и валюта → Всегда Decimal

Никаких исключений. Цены, налоги, зарплаты, скидки — только decimal. Используйте суффикс m (money) для литералов: decimal salary =

Блоги

Рекомендаций по книгам