Різниця між числовим, плаваючим і десятковим у SQL Server


322

Які відмінності між numeric, floatі decimalтипи даних і які повинні бути використані в яких ситуаціях?

Для будь-якого виду фінансових операцій (наприклад, у галузі заробітної плати), який із них є кращим і чому?


1
Десяткове та числове посилання вище потребує оновлення до docs.microsoft.com/en-us/sql/t-sql/data-types/… . Посилання вище не існує.
Найджел Айнско

1
Зазвичай при роботі з фінансовими суб'єктами цікаво працювати з типами Integer , крім плаваючої крапки , і зберігати цінні центри , наприклад, замість доларів , наприклад.
Педро

Відповіді:


494

використовуйте поплавкові або реальні типи даних лише у тому випадку, якщо точність, що надається десятковим (до 38 цифр), недостатня

  • Орієнтовні числові типи даних не зберігають точних значень, визначених для багатьох чисел; вони зберігають надзвичайно близьке наближення значення. ( Technet )

  • Уникайте використання плаваючих чи реальних стовпців в умовах пошуку пункту WHERE, особливо операторів = і <> ( Technet )

тому загалом тому, що точність, що надається десятковим знаком, становить [10E38 ~ 38 цифр], якщо ваш номер може вміститися в ньому, а менший простір для зберігання (і, можливо, швидкість) Float не важливий, а справа з ненормальною поведінкою та питаннями приблизних числових типів не є прийнятно, використовувати Decimal взагалі .

більше корисної інформації

  • числовий = десятковий (від 5 до 17 байт) ( точний числовий тип даних)
    • відобразиться на десяткові числа в .NET
    • обидва мають (18, 0) параметри за замовчуванням (точність, масштаб) у SQL-сервері
    • шкала = максимальна кількість десяткових цифр, які можна зберігати праворуч від десяткової коми.
    • просимо зауважити, що гроші (8 байт) і дрібні гроші (4 байти) також точні і відображаються в десятковий In .NET і мають 4 знаки після коми ( MSDN )
    • десятковий і числовий (Transact-SQL) - MSDN
  • реальна (4 байти) ( приблизний числовий тип даних)
  • float (8 байт) ( приблизний числовий тип даних)
    • відобразиться до Double у .NET
  • Всі точні числові типи завжди дають однаковий результат, незалежно від того, який тип архітектури процесора використовується або величини чисел
  • Параметр, що подається до типу даних поплавця, визначає кількість бітів, які використовуються для зберігання мантіси числа плаваючої точки .
  • Орієнтовний числовий тип даних зазвичай використовує менший обсяг пам’яті та має кращу швидкість (до 20x), і ви також повинні врахувати, коли вони конвертуються у .NET

Точні числові типи даних Орієнтовні числові типи даних

основне джерело : Навчальний комплект MCTS з автоматичним темпом (іспит 70-433): Розробка бази даних Microsoft® SQL Server® 2008 - Розділ 3 - Таблиці, типи даних та декларативна цілісність даних Урок 1 - Вибір типів даних (Керівні принципи) - Сторінка 93


17
use the float or real data types only if the precision provided by decimal is insufficient- Я подумав, що реальне МЕНШЕ точніше, ніж десяткові, так як прийти записувати використовувати реальне, якщо десятків недостатньо?
BornToCode

7
real менш менш точний, тому не рекомендується, якщо не зберігати великі числа, що перевищують десятковий (> 10e38), або не враховувати пробіл. я здогадуюсь, точність тут у цитаті означає можливі значення та величину, а не точність
Іман

11
@BornToCode "Точність" тут стосується того, наскільки широкі значення ви хочете зберегти. якщо вам потрібно зберігати значення між 1e10 та 1e-10, тоді decimalбуде просто добре. Це точність 20. Якщо вам потрібно зберігати значення між, скажімо, 1e20 та 1e-20, ну, decimal не можу цього зробити. Це 40 цифр точності. Ніколи не можна зберігати 1e20 та 1e-20 в одному decimalполі. Натомість ви можете використовувати float, який внутрішньо зберігає все як журнал бази 2. Це дозволяє забезпечити повний діапазон точності в одному полі з недоліком того, що тільки перші ~ 8 цифр будуть точними.
Беконові шматочки

Я треті коментарі BornToCode та Іман. Я щойно експериментував (використовуючи SQL Server 2012), і, здається, машина epsilon для float (53), типу з плаваючою точкою найвищої точності, є 2.22044604925031E-16. Таким чином, ви отримаєте близько 15 значущих цифр з цього. З іншого боку, я можу отримати 38 значущих цифр із десяткової.
Стюарт

"Використовуйте float..." - сказав хто? Це цитата чи ваша думка?
користувач443854

24

Вказівки від MSDN: Використання десяткових, плаваючих та реальних даних

Максимальна точність числових і десяткових типів даних за замовчуванням становить 38. У Transact-SQL числовий функціонально еквівалентний десятковому типу даних. Використовуйте десятковий тип даних, щоб зберігати номери з десятковістю, коли значення даних потрібно зберігати точно так, як зазначено.

Поведінка плаваючого та реального слід за специфікацією IEEE 754 щодо приблизних числових типів даних. Через приблизний характер плаваючих та реальних типів даних не використовуйте ці типи даних, коли потрібна точна чисельна поведінка, наприклад, у фінансових програмах, в операціях, пов’язаних із округленням, або при перевірці рівності. Замість цього використовуйте цілі, десяткові, грошові чи малі типи грошей. Уникайте використання плаваючих або реальних стовпців в умовах пошуку WHERE, особливо операторів = і <>. Найкраще обмежити поплавкові та реальні стовпці на> або <порівняння.


У Scaleстовпці вказано (фіксовану) кількість десяткових знаків .
Cees Timmerman

1
Якщо ви хочете "точно так, як зазначено", то, з точки зору стандартів, є певна перевага, numericоскільки він ніколи не зберігатиметься з більшою точністю, ніж ви просили: див. Stackoverflow.com/a/759606/626804
Ed Avis,

13

Не повна відповідь, а корисне посилання:

"Я часто роблю обчислення проти десяткових значень. У деяких випадках перенесення десяткових значень на плаваючий ASAP перед будь-якими розрахунками дає кращу точність."

http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/12/20/for-better-precision-cast-decimals-before-calculations.aspx


2
Це не має сенсу. Усі інші відповіді з джерелами говорять про те, що числові чи десяткові типи даних є точними, а float або real type - дуже близьким наближенням. Завдяки меншій точності я можу зрозуміти, що лиття в плавати може дати можливість швидших розрахунків, але не більш високу точність.
cbaldan

3
Усі числові типи даних можуть відчувати переповнення та перелив. Переповнення - явна помилка, однак, переповнення беззвучне. Характеристика підтоку для decimalта floatє відрізнятися . Десятковий засіб максимально захищає від переливу, збільшуючи точність або масштаб. Однак, як тільки ви потрапите на межу значущих цифр у десятковій частині, підтоки замовчуються (і точність втрачається). Float має ширший діапазон масштабу, і саме обмеження масштабу є причиною переливу. Таким чином, поплавок може мати кращі масштаби. Тим не менш, це все ще неточний тип.
ЕрікЕ

13

Вони відрізняються в пріоритетності типу даних

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

SELECT SQL_VARIANT_PROPERTY(CAST(1 AS NUMERIC) + CAST(1 AS DECIMAL),'basetype')

Отриманий тип даних є числовим, оскільки він має перевагу типу даних .

Вичерпний перелік типів даних за пріоритетністю:

Посилання на посилання


7

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

EDIT (не вдалося прочитати все запитання): Float (53) (він же реальний) - це число з плаваючою точкою з подвійною точністю (32 біт) у SQL Server. Regular Float - це одноточне число з плаваючою точкою. Double - це гарне поєднання точності та простоти для багатьох обчислень. Ви можете створити дуже високе число точності з десятковою - до 136 біт, - але ви також повинні бути обережними, щоб визначити свою точність і масштаб правильно, щоб вона могла містити всі ваші проміжні обчислення до необхідної кількості цифр.


Ви не вказали, що є кращим, поки справа стосується фінансових операцій і чому?
priyanka.sarkar

Для SQL Server 2008 та новіших версій float (53) aka float - це число з плаваючою точкою подвійної точності (64-бітне), тоді як float (24) aka real - це одноточне (32-бітове) число з плаваючою точкою. docs.microsoft.com/en-us/sql/t-sql/data-types/float-and-real-transact-sql
M Kloster

4

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

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

Перетворення з десяткової або числової цифри в плаваючу може призвести до певної втрати точності. Для типів даних з десятковою чисельною чисельністю SQL Server розглядає кожну конкретну комбінацію точності та масштабу як різний тип даних. DECIMAL (2,2) та DECIMAL (2,4) - різні типи даних. Це означає, що 11.22 та 11.2222 є різними типами, хоча це не стосується float. Для FLOAT (6) 11.22 та 11.2222 є тими ж типом даних.

Ви також можете використовувати гроші типу даних для економії грошей. Це рідний тип даних із 4-цифрною точністю до грошей. Більшість експертів вважає за краще цей тип даних для економії грошей.

Довідка 1 2 3


3

Справа для десяткової

У чому це основна потреба?

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

Врахуйте це:

0.1 (decimal, or "base 10") = .00011001100110011... (binary, or "base 2")

Вищеописаний еліпсис [...] означає «нескінченний». Якщо ви уважно подивитесь на це, з’являється нескінченний повторюваний візерунок (= '0011')

Отже, в якийсь момент комп'ютер повинен округлити це значення. Це призводить до помилок накопичення, що виникають внаслідок багаторазового використання чисел, які точно зберігаються.

Скажіть, що ви хочете зберігати фінансові суми (це числа, які можуть мати дробову частину). Перш за все, ви не можете використовувати цілі числа очевидно (цілі числа не мають дробової частини). З чисто математичної точки зору природною тенденцією було б використання аfloat . Але в комп’ютері плавці мають ту частину числа, яка розташована після десяткової крапки - "мантіса" - обмежена. Це призводить до помилок округлення.

Щоб подолати це, комп'ютери пропонують конкретні типи даних, які обмежують похибку двійкового округлення в комп’ютерах на десяткові числа. Це тип даних, який слід абсолютно використовувати для представлення фінансових сум. Зазвичай ці типи даних походять за назвою Decimal. Так, наприклад, у C #. Або DECIMALв більшості баз даних.


1

Хоча питання не включає тип даних MONEY, деякі люди, що стикаються з цією ниткою, можуть спокуситись використовувати тип даних MONEY для фінансових розрахунків.

Будьте уважні до типу даних ГРОШІ, це обмежена точність.

Є багато хорошої інформації про це у відповідях на це питання Stackoverflow:

Чи слід вибрати типи даних MONEY або DECIMAL (x, y) у SQL Server?

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