Ответ
Типы double и decimal предназначены для чисел с плавающей запятой, но имеют фундаментальные различия в представлении, точности и применении.
| Критерий | double (System.Double) |
decimal (System.Decimal) |
|---|---|---|
| Стандарт | IEEE 754 (двоичный) | Десятичный (base-10) |
| Размер | 64 бита (8 байт) | 128 бит (16 байт) |
| Точность | ~15-16 десятичных знаков | ~28-29 десятичных знаков |
| Диапазон | Огромный (±5.0 × 10^−324 до ±1.7 × 10^308) | Меньший (±1.0 × 10^−28 до ±7.9 × 10^28) |
| Основная проблема | Ошибки двоичного представления (например, 0.1) | Нет ошибок представления для десятичных чисел |
| Производительность | Высокая (аппаратная поддержка FPU) | Ниже (программная эмуляция) |
| Сфера применения | Научные вычисления, 3D-графика, симуляции | Финансовые расчеты, денежные суммы, бухгалтерия |
Ключевой пример ошибки округления double:
double d = 0.1 + 0.2;
Console.WriteLine(d == 0.3); // False!
Console.WriteLine(d); // 0.30000000000000004
// Для decimal используется суффикс 'm'
decimal m = 0.1m + 0.2m;
Console.WriteLine(m == 0.3m); // True
Console.WriteLine(m); // 0.3
Рекомендация:
- Используйте
decimalдля всех финансовых операций, где важна точность десятичных расчетов (цена, налог, процент). - Используйте
doubleдля вычислений, где важна скорость и диапазон, а небольшая погрешность допустима (физика, координаты, статистика).
Ответ 18+ 🔞
Ну слушай, смотри, есть два типа для чисел с плавающей точкой — double и decimal. И они, блядь, как небо и земля, хотя на первый взгляд одно и то же. Просто один для учёных, а другой для бухгалтеров, которые с каждой копейкой считаются.
Вот смотри, табличка, чтобы не запутаться:
| Критерий | double (System.Double) |
decimal (System.Decimal) |
|---|---|---|
| Как внутри устроен | По стандарту IEEE 754 (двоичный) | По-человечески, десятичный (base-10) |
| Сколько жрёт памяти | 64 бита (8 байт) | 128 бит (16 байт) — в два раза больше! |
| Точность | Примерно 15-16 знаков после запятой | Целых 28-29 знаков, представляешь? |
| Диапазон значений | Охуенно огромный (±5.0 × 10^−324 до ±1.7 × 10^308) | Поменьше, но всё равно дохуя (±1.0 × 10^−28 до ±7.9 × 10^28) |
| Главная засада | Ошибки из-за двоичного представления (например, 0.1) | Для десятичных дробей ошибок нет, красота |
| Скорость | Высокая, железо его напрямую поддерживает | Ниже, потому что софтовые вычисления |
| Где юзать | Наука, графика, игры — где скорость важнее | Финансы, деньги, бухгалтерия — где каждая копейка на счету |
А теперь самый сок, пример, от которого мозг вытекает. Берём double:
double d = 0.1 + 0.2;
Console.WriteLine(d == 0.3); // False, блядь!
Console.WriteLine(d); // 0.30000000000000004 — вот же ж ёбаный насос!
Видишь? Сложил 0.1 и 0.2, а получил какую-то хуйню. Это потому что внутри он двоичный, и для него 0.1 — это бесконечная дробь, как пилить сук, на котором сидишь.
А теперь decimal (не забудь суффикс 'm', а то опять обосрёшься):
decimal m = 0.1m + 0.2m;
Console.WriteLine(m == 0.3m); // True, ура!
Console.WriteLine(m); // 0.3 — всё чисто, как слёзы младенца.
Вот и весь сказ. Итог простой, как три копейки:
- Если делаешь что-то с деньгами — цена, налог, зарплата — только
decimal. Иначе потом бухгалтер придёт и ебальник набьёт за потерянную копейку. - Если гоняешь полигоны, считаешь траектории или делаешь научные расчёты — бери
double. Он быстрый, и погрешность в десятом знаке тебя волновать не должна.