Різниця між десятковим, плаваючим та подвійним у .NET?


Відповіді:


2265

floatі doubleє плаваючими двійковими типами . Іншими словами, вони представляють таке число:

10001.10010110011

Двійкове число та розташування двійкової точки обоє кодуються у межах значення.

decimalє плаваючою десятковою точки типу . Іншими словами, вони представляють таке число:

12345.65789

Знову ж таки, число та розташування десяткової крапки кодуються у межах значення - саме це робить decimalтип плаваючої крапки замість типу фіксованої точки.

Важливо зазначити, що люди звикли представляти не цілі числа у десятковій формі і очікувати точних результатів у десяткових поданнях; не всі десяткові числа точно представлені у двійковій плаваючій точці - наприклад, 0,1 - тому, якщо ви використовуєте двійкове значення з плаваючою комою, ви отримаєте наближення до 0,1. Ви все одно отримаєте наближення і при використанні плаваючої десяткової крапки - результат поділу 1 на 3 не може бути точно представлений, наприклад.

Що ж робити, коли:

  • Для значень, які є "природно точними десятичниками", це добре використовувати decimal. Зазвичай це підходить для будь-яких понять, винайдених людиною: фінансові цінності є найбільш очевидним прикладом, але є й інші. Розглянемо, наприклад, оцінку, надану дайверам або фігуристам.

  • Для значень, які є більш артефактами природи, які реально неможливо точно виміряти , float/ doubleє більш підходящими. Наприклад, наукові дані зазвичай представлені у цій формі. Тут початкові значення не будуть "десятково точними" для початку, тому для очікуваних результатів не важливо підтримувати "десяткову точність". Типи бінарних точок з плаваючою точкою працювати набагато швидше, ніж десяткові.


58
float/ doubleзазвичай не представляють числа, як 101.101110правило, це представлено як щось на зразок 1101010 * 2^(01010010)- показника
Mingwei Samuel

79
@Hazzard: Ось що означає відповідь "та розташування двійкової точки".
Джон Скіт

112
Я здивований, що це ще не було сказано, floatце ключове слово з псевдонімом C # і не є .Net. це System.Single.. singleі doubleє плаваючими двозначними типами.
Бретт Касвелл

54
@BKSpurgeon: Ну, тільки так, як ви можете сказати, що все є бінарним типом, і в цей момент це стає досить марним визначенням. Десяткові знаки - це десятковий тип, оскільки це число, представлене як ціле число, і значення масштабу, таким чином, що результат є значущим та масштабом * 10 ^, тоді як плаваючий та подвійний - значущий * 2 ^ масштаб. Ви берете число, написане в десятковій формі, і переміщуєте десяткову точку досить праворуч, щоб у вас було ціле число, щоб опрацювати значення та масштаб. Для float / double ви б почали з числа, записаного у двійковій формі.
Джон Скіт

21
Ще одна відмінність: float 32-бітний; подвійний 64-розрядний; і десятковий 128-розрядний.
Девід

1072

Точність - головна відмінність.

Float - 7 цифр (32 біт)

Подвійні -15-16 цифр (64 біт)

Десяткові -28-29 значущих цифр (128 біт)

Десяткові знаки мають значно більшу точність і зазвичай використовуються у фінансових програмах, які вимагають високого ступеня точності. Десяткові знаки значно повільніші (до 20X разів у деяких тестах), ніж подвійний / поплавковий.

Десяткові знаки і поплавці / парні порівнювання не можна порівняти без відступу, тоді як поплавці і парні можуть. Десяткові знаки також дозволяють кодувати або відмінювати нулі.

float flt = 1F/3;
double dbl = 1D/3;
decimal dcm = 1M/3;
Console.WriteLine("float: {0} double: {1} decimal: {2}", flt, dbl, dcm);

Результат:

float: 0.3333333  
double: 0.333333333333333  
decimal: 0.3333333333333333333333333333

65
@Thecrocodilehunter: вибачте, але ні. Десяткові знаки можуть представляти всі числа, які можуть бути представлені у десятковій нотації, але не 1/3, наприклад. 1,0 м / 3,0 м буде оцінюватися до 0,33333333 ... з великим, але кінцевим числом 3s в кінці. Помноживши його на 3, не повернеться точно 1,0.
Ерік П.

50
@Thecrocodilehunter: Я думаю, що ви плутаєте точність і точність. У цьому контексті вони різні речі. Точність - це кількість цифр, доступних для представлення числа. Чим більше точності, тим менше потрібно круглити. Жоден тип даних не має нескінченної точності.
Ігбі Ларгеман

13
@Thecrocodilehunter: Ви припускаєте, що значення, яке вимірюється, саме таке 0.1 - що рідко трапляється в реальному світі! Будь-який кінцевий формат зберігання зв'яже нескінченну кількість можливих значень з кінцевою кількістю бітових шаблонів. Наприклад, floatconflate 0.1і 0.1 + 1e-8, поки decimalбуде conflate 0.1і 0.1 + 1e-29. Впевнені, що в заданому діапазоні певні значення можуть бути представлені у будь-якому форматі з нульовою втратою точності (наприклад, floatможна зберігати будь-яке ціле число до 1,6e7 з нульовою втратою точності) - але це все ще не безмежна точність.
Даніель Приден

27
@Thecrocodilehunter: Ви пропустили мою думку. 0.1це не спеціальне значення ! Єдине, що робить 0.1«кращим», ніж 0.10000001це тому, що людям подобається база 10. І навіть зі floatзначенням, якщо ініціалізувати два значення 0.1однаковим чином, вони обидва будуть однаковими . Просто це значення точно не буде 0.1- воно буде найближчим до того, 0.1яке може бути точно представлено якfloat . Звичайно, з двійковими плавцями (1.0 / 10) * 10 != 1.0, але з десятковими плавцями (1.0 / 3) * 3 != 1.0також. Жоден з них не є абсолютно точним.
Даніель Приден

16
@Thecrocodilehunter: Ви все ще не розумієте. Я не знаю, як це сказати простіше: У С, якщо ви це зробите, double a = 0.1; double b = 0.1;то a == b буде правдою . Це просто так aі bбудуть обидва не зовсім рівні 0.1. У C #, якщо ви це зробите, decimal a = 1.0m / 3.0m; decimal b = 1.0m / 3.0m;то a == bтакож буде правдою. Але в такому випадку ні те, aні точно не bбудуть рівними - вони обидва рівні . В обох випадках певна точність втрачається через представлення. Ви вперто говорите, що має "нескінченну" точність, що помилково . 1/30.3333...decimal
Даніель Приден

84

Десяткова структура суворо орієнтована на фінансові розрахунки, що вимагають точності, що відносно нетерпимо до округлення. Десяткові знаки не є достатніми для наукових застосувань, однак з кількох причин:

  • Певна втрата точності є прийнятною у багатьох наукових розрахунках через практичні межі фізичної проблеми або артефакту, що вимірюється. Втрата точності неприйнятна у фінансах.
  • Десяткові знаки значно (набагато) повільніше, ніж плаваючі та подвійні для більшості операцій, насамперед тому, що операції з плаваючою комою виконуються у двійкових, тоді як десяткові речі виконуються в базі 10 (тобто поплавці та подвійні елементи обробляються апаратними засобами FPU, такими як MMX / SSE , тоді як десяткові знаки обчислюються програмним забезпеченням).
  • Десяткові знаки мають неприпустимо менший діапазон значень, ніж подвійний, незважаючи на те, що він підтримує більше цифр точності. Тому десяткові цифри не можна використовувати для представлення багатьох наукових цінностей.

5
Якщо ви робите фінансові розрахунки, вам абсолютно доведеться прокручувати власні типи даних або знайти хорошу бібліотеку, яка відповідає вашим точним потребам. Точність у фінансовій обстановці визначається органами (людськими) стандартами, і вони мають дуже конкретні локалізовані (як у часі, так і в географії) правила щодо розрахунків. Такі речі, як правильне округлення, не зафіксовані у простих числових типах даних у .Net. Здатність робити обчислення - це лише дуже мала частина загадки.
Джеймс Мур

76
+---------+----------------+---------+----------+---------------------------------------------+
| C#      | .Net Framework | Signed? | Bytes    | Possible Values                             |
| Type    | (System) type  |         | Occupied |                                             |
+---------+----------------+---------+----------+---------------------------------------------+
| sbyte   | System.Sbyte   | Yes     | 1        | -128 to 127                                 |
| short   | System.Int16   | Yes     | 2        | -32768 to 32767                             |
| int     | System.Int32   | Yes     | 4        | -2147483648 to 2147483647                   |
| long    | System.Int64   | Yes     | 8        | -9223372036854775808 to 9223372036854775807 |
| byte    | System.Byte    | No      | 1        | 0 to 255                                    |
| ushort  | System.Uint16  | No      | 2        | 0 to 65535                                  |
| uint    | System.UInt32  | No      | 4        | 0 to 4294967295                             |
| ulong   | System.Uint64  | No      | 8        | 0 to 18446744073709551615                   |
| float   | System.Single  | Yes     | 4        | Approximately ±1.5 x 10-45 to ±3.4 x 1038   |
|         |                |         |          |  with 7 significant figures                 |
| double  | System.Double  | Yes     | 8        | Approximately ±5.0 x 10-324 to ±1.7 x 10308 |
|         |                |         |          |  with 15 or 16 significant figures          |
| decimal | System.Decimal | Yes     | 12       | Approximately ±1.0 x 10-28 to ±7.9 x 1028   |
|         |                |         |          |  with 28 or 29 significant figures          |
| char    | System.Char    | N/A     | 2        | Any Unicode character (16 bit)              |
| bool    | System.Boolean | N/A     | 1 / 2    | true or false                               |
+---------+----------------+---------+----------+---------------------------------------------+

Дивіться тут для отримання додаткової інформації .


5
Ви залишили найбільшу різницю, яка є базовою для десяткових типів (десяткова частина зберігається як 10, всі інші числові типи, перелічені, є базовою 2).
BrainSlugs83

1
Діапазони значень для одинарного та подвійного зображуються неправильно на зображенні, наведеному вище, або у вихідному дописі на форумі. Оскільки ми не можемо легко переписати текст тут, використовуйте символ карети: Одномісний має бути 10 ^ -45 та 10 ^ 38, а Double - 10 ^ -324 та 10 ^ 308. Також MSDN має поплавок з діапазоном від -3,4x10 ^ 38 до + 3,4x10 ^ 38. Шукайте MSDN для System.Single та System.Double у разі зміни посилань. Одномісний: msdn.microsoft.com/en-us/library/b1e65aza.aspx Подвійний: msdn.microsoft.com/en-us/library/678hzkk9.aspx
deegee

2
Десяткове число - 128 біт ... означає, що він займає 16 байт, а не 12
користувач1477332

51

Я не повторюю багато хорошої (а також поганої) інформації, про яку вже відповіли в інших відповідях та коментарях, але я відповім на ваше подальше запитання порадою:

Коли хтось скористався б одним із них?

Використовуйте десятковий для підрахованих значень

Використовуйте float / double для вимірюваних значень

Деякі приклади:

  • гроші (ми рахуємо гроші чи міряємо гроші?)

  • відстань (чи вважаємо ми відстань чи вимірюємо відстань? *)

  • бали (чи вважаємо ми бали чи вимірюємо бали?)

Ми завжди рахуємо гроші і ніколи не повинні їх вимірювати. Зазвичай ми вимірюємо відстань. Ми часто підраховуємо бали.

* У деяких випадках, як я б назвав номінальну відстань , ми дійсно можемо захотіти «рахувати» відстань. Наприклад, можливо, ми маємо справу зі знаками країни, які показують відстані до міст, і ми знаємо, що ці відстані ніколи не мають більше однієї десяткової цифри (xxx.x km).


1
Мені дуже подобається ця відповідь, особливо питання "чи рахуємо ми чи міряємо гроші?" Однак, окрім грошей, я не можу придумати нічого, що «підраховується», що не є просто цілим числом. Я бачив деякі програми, які використовують десятковий просто тому, що у подвійних є занадто мало значущих цифр. Іншими словами, десятковий може бути використаний, оскільки у C # немає чотириразового типу en.wikipedia.org/wiki/Quadruple-precision_floating-point_format
Джон Генкель

48

float 7 цифр точності

double має близько 15 цифр точності

decimal має близько 28 цифр точності

Якщо вам потрібна краща точність, використовуйте подвійний замість поплавця. У сучасних процесорах обидва типи даних мають майже однакову продуктивність. Єдиною користю використання float є те, що вони займають менше місця. Практично це має значення лише в тому випадку, якщо у вас їх багато.

Я виявив, що це цікаво. Що повинен знати кожен вчений-комп’ютер про арифметику з плаваючою комою


1
@RogerLipscombe: Я вважав би doubleналежним у бухгалтерському обліку додатків у тих випадках (і в основному лише тих випадках), коли жодного цілого типу, що перевищує 32 біти, не було, а цей doubleвикористовується як би 53-розрядний цілочисельний тип (наприклад, для утримання ціла кількість копійок, або ціла кількість сотих відсотків). В даний час для таких речей не так вже й багато, але багато мов отримали можливість використовувати значення з плаваючою комою з подвоєною точністю задовго до того, як вони отримали 64-бітну (а в деяких випадках навіть 32-бітну!) Цілочисельну математику.
supercat

1
Ваша відповідь означає, що точність є єдиною різницею між цими типами даних. Враховуючи арифметику двійкових плаваючих точок, як правило, реалізується в апаратному ФПУ , продуктивність є суттєвою різницею. Для деяких програм це може бути малозначимим, але для інших критично важливим.
saille

6
@supercat подвійний ніколи не є правильним у бухгалтерських програмах. Тому що Double може лише наближати десяткові значення (навіть у межах власної точності). Це відбувається тому, що подвійне зберігає значення у базовому-2 (бінарному) -центричному форматі.
BrainSlugs83

2
@ BrainSlugs83: Використання типів з плаваючою комою для розміщення величин, що не мають цілої кількості, було б неправильним, але в мовах історично дуже часто було типів з плаваючою комою, які могли б точно представляти більші значення цілих чисел, ніж їх цілі типи могли представляти . Мабуть, самий крайній приклад - Turbo-87, лише цілі типи якого обмежувались від -32768 до +32767, але чиї RealIIRC могли представляти значення до 1,8E + 19 з точністю одиниці. Я думаю, було б набагато безпечніше, щоб облікова програма використовувала Realдля представлення цілої кількості копійок, ніж ...
supercat

1
... щоб спробувати виконати багатоточну математику, використовуючи купу 16-бітних значень. Для більшості інших мов різниця була не такою екстремальною, але тривалий час дуже часто в мовах не було жодного цілого типу, який би виходив за межі 4E9, але мав doubleтип, що мав одиничну точність до 9E15. Якщо потрібно зберігати цілі числа, які перевищують найбільший доступний цілочисельний тип, використання doubleможе бути простішим та ефективнішим, ніж намагатися підробити багатоточну математику, особливо зважаючи на те, що в той час як процесори мають інструкції виконувати 16x16-> 32 або. ..
supercat

36

Про це ніхто не згадував

У налаштуваннях за замовчуванням Floats (System.Single) і подвійні (System.Double) ніколи не використовуватимуть перевірку переповнення, тоді як Decimal (System.Decimal) завжди використовуватиме перевірку переповнення.

я маю на увазі

decimal myNumber = decimal.MaxValue;
myNumber += 1;

кидає OverflowException .

Але це не так:

float myNumber = float.MaxValue;
myNumber += 1;

&

double myNumber = double.MaxValue;
myNumber += 1;

1
float.MaxValue+1 == float.MaxValue, так само decimal.MaxValue+0.1D == decimal.MaxValue. Можливо, ви мали на увазі щось подібне float.MaxValue*2?
supercat

@supercar Але це неправда, що десяткова. Maxxal + 1 == десятична.
Max-

@supercar decimal.MaxValue + 0.1m == decimal.MaxValue ok
GorkemHalulu

1
System.DecimalКидає виняток як раз перед його стає в змозі розрізняти цілі одиниці, але якщо програма має мати справу, наприклад , з доларами і центами, що може бути занадто пізно.
supercat

28
  1. Double і float можна розділити на цілий нуль без винятку як при компіляції, так і під час виконання.
  2. Десяткові числа не можна розділити на цілий нуль. Компіляція завжди буде невдалою, якщо ви це зробите.

6
Вони точно впевнені! Вони також мають кілька "магічних" значень, таких як Нескінченність, Негативна Нескінченність та NaN (не число), що робить його дуже корисним для виявлення вертикальних ліній під час обчислення нахилів ... Далі, якщо вам потрібно вирішити між викликом float .TryParse, double.TryParse і decimal.TryParse (щоб виявити, чи є рядок числом, наприклад), я рекомендую використовувати double або float, оскільки вони будуть правильно розбирати "Infinity", "Infinity" і "NaN". , тоді як десяткових не буде.
BrainSlugs83

Компіляція завершується невдачею, якщо ви намагаєтесь розділити літерал decimalна нуль (CS0020), і те саме стосується інтегральних літералів. Однак якщо десяткове значення часу виконання розділене нулем, ви отримаєте виняток, а не помилку компіляції.
Дрю Ноакс

@ BrainSlugs83 Однак, можливо, ви не хочете розбирати "Нескінченність" або "NaN" залежно від контексту. Здається, що це хороший подвиг для введення користувача, якщо розробник недостатньо строгий.
Зима

28

Цілі числа, як було сказано, - це цілі числа. Вони не можуть зберігати точку чогось, наприклад, .7, .42 та .007. Якщо вам потрібно зберігати номери, які не є цілими числами, вам потрібна інша тип змінної. Можна використовувати подвійний або поплавковий тип. Ви налаштовуєте ці типи змінних точно так само: замість слова intвведіть doubleабо float. Подобається це:

float myFloat;
double myDouble;

( floatскорочується "плаваюча точка", і просто означає число з точкою, що знаходиться на кінці.)

Різниця між ними полягає у розмірі чисел, які вони можуть утримувати. Бо у floatвас може бути до 7 цифр. Для doubles ви можете мати до 16 цифр. Якщо точніше, ось офіційний розмір:

float:  1.5 × 10^-45  to 3.4 × 10^38  
double: 5.0 × 10^-324 to 1.7 × 10^308

floatє 32-бітним числом і doubleє 64-бітним числом.

Двічі клацніть нову кнопку, щоб отримати код. Додайте до коду кнопки такі три рядки:

double myDouble;
myDouble = 0.007;
MessageBox.Show(myDouble.ToString());

Зупиніть програму та поверніться до вікна кодування. Змініть цей рядок:

myDouble = 0.007;
myDouble = 12345678.1234567;

Запустіть програму і натисніть подвійну кнопку. У вікні повідомлення правильно відображається номер. Додайте ще одне число в кінці, і C # знову закруглиться вгору або вниз. Мораль - якщо ви хочете точності, будьте уважні до округлення!


2
Згадане вами "щось таке", як правило, називається "дробовою частиною" числа. "Плаваюча точка" не означає "число, яке має точку в кінці"; але натомість "Плаваюча точка" розрізняє тип числа, на відміну від числа "Фіксована точка" (яка також може зберігати дробове значення); різниця полягає в тому, чи точність фіксована, чи плаваюча. - Числа з плаваючою комою дають набагато більший динамічний діапазон значень (Min та Max) за ціною точності, тоді як цифри з фіксованою точкою дають вам постійну точність за ціною діапазону.
BrainSlugs83

16
  • float: ± 1,5 x 10 ^ -45 до ± 3,4 x 10 ^ 38 (~ 7 значущих цифр
  • подвійний: ± 5,0 х 10 ^ -324 до ± 1,7 х 10 ^ 308 (15-16 значущих цифр)
  • десяткова: ± 1,0 х 10 ^ -28 до ± 7,9 х 10 ^ 28 (28-29 значущих цифр)

9
Різниця - це не просто точність. - decimalнасправді зберігається у десятковому форматі (на відміну від бази 2; тому він не втрачає чи округлює цифри через перетворення між двома числовими системами); крім того, decimalне має поняття спеціальних значень, таких як NaN, -0, ∞ або -∞.
BrainSlugs83

13

Це було цікавою темою для мене, тому що сьогодні у нас щойно помилковий помилок, щодо decimalменшої точності, ніж float.

У нашому C # коді ми зчитуємо числові значення з електронної таблиці Excel, перетворюємо їх у формат a decimal, а потім відправляємо це decimalназад в Сервіс для збереження в базу даних SQL Server .

Microsoft.Office.Interop.Excel.Range cell = 
object cellValue = cell.Value2;
if (cellValue != null)
{
    decimal value = 0;
    Decimal.TryParse(cellValue.ToString(), out value);
}

Тепер, майже для всіх наших значень Excel, це спрацювало чудово. Але для деяких, дуже малих значень Excel, використовуючи decimal.TryParseвтрачене значення повністю. Один з таких прикладів

  • cellValue = 0,00006317592

  • Decimal.TryParse (cellValue.ToString (), значення); // поверне 0

Рішенням, химерно, було перетворення значень Excel у doubleспочатку, а потім у decimal:

Microsoft.Office.Interop.Excel.Range cell = 
object cellValue = cell.Value2;
if (cellValue != null)
{
    double valueDouble = 0;
    double.TryParse(cellValue.ToString(), out valueDouble);
    decimal value = (decimal) valueDouble;
    
}

Незважаючи на те, що doubleмає меншу точність, ніж а decimal, це насправді гарантувало, що невелика кількість все одно буде визнана. Чомусь double.TryParseнасправді вдалося отримати такі невеликі числа, тоді як decimal.TryParseвстановило б їх до нуля.

Незвичайно. Дуже дивно.


3
З цікавості, якою була нераціональна цінність cellValue.ToString ()? Decimal.TryParse ("0,00006317592", поза вал), здається, працює ...
micahtan

11
-1 Не зрозумійте мене неправильно, якщо це правда, це дуже цікаво, але це окреме питання, це точно не відповідь на це питання.
Вестон

2
Можливо тому, що клітинка Excel повертала подвійне значення, а значення ToString () становило "6.31759E-05", отже, decimal.Parse () не сподобалось позначенням. Б'юсь об заклад, якби ви перевірили повернене значення Decimal.TryParse (), воно було б помилковим.
SergioL

2
@weston Answers часто доповнюють інші відповіді, заповнюючи пропущені нюанси. Ця відповідь підкреслює різницю з точки зору розбору. Це дуже відповідь на питання!
Робіно

1
Ер ... decimal.Parse("0.00006317592")працює - у вас щось інше відбувається. - Можливо, наукове позначення?
BrainSlugs83

8

Для таких програм, як ігри та вбудовані системи, де пам'ять та продуктивність є критичними, плаваючий зазвичай є числовим типом вибору, оскільки він швидший і вдвічі менший. Цілими колись були зброєю вибору, але продуктивність з плаваючою комою випередила цілі числа в сучасних процесорах. Десяткові цифри прямо виходять!


Практично всі сучасні системи, навіть мобільні телефони, мають апаратну підтримку для подвійних; і якщо у грі є навіть проста фізика, ви помітите велику різницю між double та float. (Наприклад, обчислюючи швидкість / тертя в простому клоні астероїдів, подвійні дозволяють прискоренню текти набагато більш текуче, ніж плавати. - Здається, це не має значення, але це абсолютно так.)
BrainSlugs83

Парні також вдвічі перевищують розміри поплавців, тобто вам потрібно пережовувати вдвічі більше даних, що шкодить вашій кеш-продуктивності. Як завжди, виміряйте та виконайте відповідні дії.
yoyo

6

Типи змінних Decimal, Double та Float відрізняються тим, що вони зберігають значення. Точність - головна відмінність, коли float - це тип даних з плаваючою точкою з одною точністю (32 біт), подвійний - тип даних з плаваючою точкою з подвійною точністю, а десяткова - це тип даних 128-бітної плаваючої точки.

Поплавок - 32 біт (7 цифр)

Подвійний - 64 біт (15-16 цифр)

Десяткові - 128 біт (28-29 значущих цифр)

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


5

Проблема всіх цих типів полягає в тому, що певна неточність існує і що ця проблема може виникати з невеликими десятковими числами, як у наступному прикладі

Dim fMean as Double = 1.18
Dim fDelta as Double = 0.08
Dim fLimit as Double = 1.1

If fMean - fDelta < fLimit Then
    bLower = True
Else
    bLower = False
End If

Запитання: Яке значення містить змінна bLower?

Відповідь: На 32-розрядній машині bLower містить ПРАВИЛЬНИЙ !!!

Якщо я заміню Double на десятковий, bLower містить FALSE, що є гарною відповіддю.

Удвічі проблема полягає в тому, що fMean-fDelta = 1.09999999999, що нижче, ніж 1,1.

Застереження: Я думаю, що така ж проблема, безумовно, може бути і для іншого числа, тому що десяткові - це лише подвійний з більшою точністю, а точність завжди є межею.

Насправді подвійний, плаваючий і десятковий відповідають БІННЯ десятковій у COBOL!

Прикро, що інші числові типи, реалізовані в COBOL, не існують у .Net. Для тих, хто не знає COBOL, в COBOL існують такі числові типи

BINARY or COMP like float or double or decimal
PACKED-DECIMAL or COMP-3 (2 digit in 1 byte)
ZONED-DECIMAL (1 digit in 1 byte) 

4

Простими словами:

  1. Типи змінних Decimal, Double та Float відрізняються тим, що вони зберігають значення.
  2. Точність - головна відмінність (зауважте, що це не єдина різниця), коли float - це тип даних плаваючої точки з одною точністю (32 біта), подвійний - тип даних з плаваючою комою з подвійною точністю, а десятковий - 128-бітний тип даних з плаваючою комою
  3. Зведена таблиця:

/==========================================================================================
    Type       Bits    Have up to                   Approximate Range 
/==========================================================================================
    float      32      7 digits                     -3.4 × 10 ^ (38)   to +3.4 × 10 ^ (38)
    double     64      15-16 digits                 ±5.0 × 10 ^ (-324) to ±1.7 × 10 ^ (308)
    decimal    128     28-29 significant digits     ±7.9 x 10 ^ (28) or (1 to 10 ^ (28)
/==========================================================================================
Ви можете прочитати більше тут , Float , Double та Decimal .


Що додає ця відповідь, яка вже не висвітлена в існуючих відповідях? До речі, ваш "або" у рядку "десятковий" неправильний: коса риса на веб-сторінці, яку ви копіюєте, вказує на поділ, а не на альтернативу.
Марк Дікінсон

1
І я сильно заперечу, що точність - головна відмінність. Основна відмінність - основа: десяткова плаваюча точка проти двійкової плаваючої точки. Ця різниця полягає в тому, що робить Decimalпридатним для фінансових заявок, і це головний критерій, який потрібно використовувати при вирішенні між Decimalі Double. Рідко трапляється, що Doubleточності недостатньо для наукових застосувань, наприклад (і Decimalчасто непридатна для наукових застосувань через обмежений діапазон).
Марк Дікінсон

2

Основна відмінність кожного з них - точність.

floatє 32-bitчисло, doubleє 64-bitчисло і decimalє 128-bitчисло.


0
  • Десяткові 128 біт (значущі цифри 28-29) У випадку фінансових застосувань краще використовувати типи десяткових знаків, оскільки це дає високий рівень точності та легко уникнути помилок округлення. Використовуйте десятковий для нецілої математики там, де потрібна точність (наприклад, гроші та валюта)

  • Подвійні 64-бітні (15-16 цифр) Подвійні типи - це, мабуть, найбільш часто використовуваний тип даних для реальних значень, за винятком обробки грошей. Використовуйте подвійний для нецілої математики, де не потрібна найточніша відповідь.

  • Плаваючий 32 біт (7 цифр) Він використовується здебільшого у графічних бібліотеках, оскільки дуже високі вимоги до потужностей обробки, а також використовуються ситуації, які можуть зазнати помилок округлення.

Decimalsнабагато повільніше, ніж a double/float.

Decimalsі Floats/Doublesне може порівнюватися без акторів, тоді як Floatsі Doublesможе.

Decimals також дозволяють кодувати або прострочувати нулі.


-1

Для визначення десяткової, плаваючої та подвійної в .Net (c #)

Ви повинні згадати значення як:

Decimal dec = 12M/6;
Double dbl = 11D/6;
float fl = 15F/6;

і перевірити результати.

І байти, які займають кожен, є

Float - 4
Double - 8
Decimal - 12
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.