Чому існує стільки числових типів (біт, int, float, double, long)?


9

Я вивчив PHP, Java та C. Тепер мені цікаво, чому існує так багато типів числових даних, як біт, int, float, double та long. Чому б не зробити лише один тип для числових?

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


6
На додаток до відповіді HorusKol: "float" та "integer" типи суттєво різні. Поплавці можуть містити дуже велику кількість, але в міру збільшення чисельності число точність знижується. Ця неточність пояснюється тим, як зберігаються поплавці. Навпаки, діапазон значень, які ви можете зберігати в цілому, досить обмежений, але значення завжди точно, тому ви можете порівняти значення набагато простіше. Також є два різних типи поведінки з поділом - цілі числа 'усікаються' до найближчого цілого числа автоматично, плаваючі не роблять. Кожна з цих форм поведінки корисна для різних ситуацій.
kampu

У Javascript є лише один тип номера на поверхні.
Есаїлія

@kampu: Насправді в багатьох мовах цілі числа можуть зберігати будь-яке число до тих пір, поки (віртуальна) пам'ять є достатньо великою, щоб її представляти.
Йорг W Міттаг

1
@ JörgWMittag: Однак, це питання, очевидно, говорить про статичні мови, а не про динамічні мови, як, наприклад, Python. Сам CPython реалізує ціле число "необмежений діапазон" у вигляді масиву 32-бітових ints, причому остаточний біт у кожному int використовується для вказівки, чи потрібно більше бітів. Також цілі числа можуть зберігати лише будь-яке ціле число. Це означає, що поплавок з нескінченним сховищем може зберігати значення до точності (нескінченний алеф один), тоді як цілі числа можуть зберігати значення лише до точності ( нескінченний алеф нуль ).
kampu

@kampu: Оскільки всі числа представлені серіями бітів, навіть із нескінченним сховищем, завжди буде однозначне зіставлення між числами з плаваючою комою та цілими числами. Тому я не думаю, що алеф ставиться до питання.
ПРИЙДАЄТЬСЯ

Відповіді:


17

Є дві причини, чому вам слід перейматися різними числовими типами даних.

1. Збереження пам’яті

for(long k=0;k<=10;k++)
{
    //stuff
}

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

2. Числа з плаваючою комою і цілі числа зберігаються по-різному в комп'ютері

Припустимо, у нас є число 22, збережене в цілому. Комп'ютер зберігає це число в пам'яті у двійковій формі як:

0000 0000 0000 0000 0000 0000 0001 0110

Якщо ви не знайомі з двійковою системою чисел, це може бути представлено в наукових позначеннях як: 2 ^ 0 * 0 + 2 ^ 1 * 1 + 2 ^ 2 * 1 + 2 ^ 3 * 0 + 2 ^ 4 * 1 + 2 ^ 5 * 0 + ... + 2 ^ 30 * 0. Останній біт може або не може бути використаний для вказівки, чи число негативне (залежно від того, чи є тип даних підписаним чи непідписаним).

По суті, це лише підсумовування значення 2 ^ (бітове місце) *.

Це змінюється, коли ви посилаєтесь на значення, що містять десяткову точку. Припустимо, у вас є число 3,75 у десятковій частині. Це називається 11.11 у двійковій формі. Ми можемо представити це як наукове позначення як 2 ^ 1 * 1 + 2 ^ 0 * 1 + 2 ^ -1 * 1 + 2 ^ -2 * 1 або, нормалізовано, як 1,111 * 2 ^ 2

Однак комп'ютер не може зберігати це: він не має явного способу вираження цієї двійкової точки (версія системи двійкових чисел десяткової крапки). Комп'ютер може зберігати лише 1 та 0. Тут надходить тип даних з плаваючою комою.

Якщо припустити, що розмір (float) становить 4 байти, то у вас є 32 біти. Першому біту присвоюється "бітовий знак". Немає підписаних поплавців чи парних пар. Наступні 8 біт використовуються для "експонента", а остаточні 23 біти використовуються як "significand" (або іноді їх називають "mantissa"). На прикладі 3,75, наш показник буде 2 ^ 1, а наше значення - 1,111.

Якщо перший біт дорівнює 1, число від’ємне. Якщо ні, позитивний. Експонент модифікується чимось під назвою "зміщення", тому ми не можемо просто зберігати "0000 0010" як показник. Зсув для числа однієї точності з плаваючою точкою - 127, а зміщення для подвійної точності (саме тут подвійний тип даних отримує свою назву) - 1023. Остаточні 23 біти зарезервовані для означенняі. Значення - це просто значення ПРАВО нашої бінарної точки.

Нашим показником буде зміщення (127) + показник (1) або представлене у двійковій формі

1000 0000

Нашим значенням буде:

111 0000 0000 0000 0000 0000

Тому 3,75 представлено у вигляді:

0100 0000 0111 0000 0000 0000 0000 0000

Тепер давайте розглянемо число 8, представлене як число з плаваючою комою і як ціле число:

0100 0001 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 1000

Як у світі комп'ютер збирається додавати 8,0 і 8? Або навіть примножувати їх !? Комп'ютер (точніше, комп'ютери x86) мають різні частини процесора, які додають числа з плаваючою комою та цілі числа.


3
3) хоч і рідко виникає проблема: Операції над числами, більшими за розмір слів комп’ютера, повільніші.
Лорен Печтел

6

Ще до того, як у нас були гігабайтні системи (або в сучасних вбудованих системах, таких як Arduino), пам’ять була преміальною, і тому були застосовані скорочені методи, щоб уточнити, скільки пам'яті займе конкретне число - BIT є простим - спочатку він займав би лише 1 біт пам'яті.

Інші розміри та назви даних різняться між системами. У 32-бітовій системі INT (або MEDIUMINT), як правило, буде 2 байти, LONGINT - 4 байти, а SMALLINT - один байт. У 64-бітних системах LONGINT може бути встановлений у 8-байт.

Навіть зараз - особливо в додатках для баз даних або програмах, на яких декілька екземплярів працює на серверах (як, наприклад, сценарії сторонніх серверів на веб-сайтах), - ви повинні бути обережними щодо того, що ви вибрали. Вибір 2, 4 або 8-байтного цілого числа для зберігання значень від 0 до 100 (яке може вміститися в один байт) є надзвичайно марним, якщо у вас є таблиця бази даних з мільйонами записів.

Більше інформації: https://en.wikipedia.org/wiki/Integer_(computer_science)


приємна відповідь +1.
Винай

7
Не тільки "назад", але і "зараз, коли система мала". На пристрої розміром Arduino один повинен бути економічним.
9000

1
Яка система використовувала лише 1 біт для зберігання трохи? біти зазвичай не можуть бути адресовані безпосередньо
jk.

1
це правда в багатьох архітектурах - але біти були безпосередньо адресовані в дійсно старих системах, і навіть в деяких останніх вбудованих системах (деякі контролери, які я запрограмував лише 10 років тому, працювали з бітами - у них було лише 64 адреси адреси певних ширин). Сьогодні я думаю, що компілятори це працюють, і розміщують їх у байтових масивах.
HorusKol

Я думаю, що головним фактором є здатність та продуктивність процесора, а не проблеми пам’яті
Джеймс,

4

На додаток до відмінних моментів cpmjr123 щодо дефіциту пам’яті та точності та розпродажів у діапазоні, thers також може бути вигідною операцією з процесора.

Більшість сучасних машин мають спеціальне обладнання для виконання операцій з плаваючою комою під назвою FPU. Існують також системи, які не мають FPU (на сьогодні це, як правило, невеликі вбудовані пристрої), отже, залежно від вашого цільового обладнання, вам доведеться взагалі не використовувати типи плаваючої крапки або використовувати бібліотеку програмного забезпечення з плаваючою комою. Навіть якщо ваша машина має FPU, історично існували відмінності в тому, які функції вона може надати. Будь-які функції, які не виконуються апаратно, повинні виконуватись у програмному забезпеченні (або уникати)

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


4

Мабуть, найголовніше, що існує дійсно три різних основних типи чисел.

ціле число, фіксований десятковий і плаваюча точка.

Всі вони поводяться по-різному.

Проста операція на зразок 7/2 може дати відповіді 3, 3,50 і 3,499 залежно від використовуваного типу даних.

"фіксований десятковий" - це тип Попелюшки, він підтримується лише на декількох мовах, таких як COBOL та VisualBasic. Комп'ютерних науковців це мало цікавить, але важливо для тих, хто подає набір рахунків або обчислює податок з продажу за рахунок-фактуру.


Я б розділив їх по-різному: дискретні числа, приблизні числа та загортання алгебраїчних кілець. Типові приклади в C буде int, floatі unsigned int, відповідно. Типи з фіксованою точкою є підкатегорією дискретних типів, але алгебраїчні кільця принципово відрізняються від чисел [обов'язок плутанини щодо непідписаних типів у С випливає з того, що вони в основному поводяться як кільця, а не числа, але не зовсім послідовні] .
supercat

3

Чи є якась користь від них?

Звичайно. Є переваги. У світі комп’ютерів пам'ять - це одне з найважливіших речей, яке слід враховувати. У чому полягає корисність пам’яті 2 кб, коли дані можуть вмістити менше 1 кб? . Оптимізації повинні бути там. Якщо ви використовуєте більше пам'яті, це, очевидно, вбиває ваші комп'ютери швидкістю в певний момент. Вам дуже подобається це мати? Немає права ...?

int - 2 bytes (16 bits)

long - 4 bytes (32 bits)

long long - 8 bytes (64 bits)

float - 4 bytes

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

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


3

цілі числа та реальні (плаваючі, подвійні) числа - це концептуально різні типи з різними наборами операцій та властивими властивостями.

Цілі ліки перелічені, але поплавці - ні.

Фактично число Float / double - це структура, що поєднує два цілі поля: mantissa та exponent. Складні номери (які ви виключили з розгляду) ще більше, ну, складні.

Будь-яка практична мова повинна мати принаймні цілі числа і плаває як окремі типи - надто різні операції над ними.


Мені не знайомі згадані вами "складні числа". Чи можете ви пояснити далі?
cpmjr123

перевірити це: en.wikipedia.org/wiki/Complex_number
c-smile

Мені відомі складні числа у вигляді + bi. Я просив більше інформації про те, як комп’ютер зберігає складні номери. Наскільки мені відомо, не існує примітивних типів даних, які б це підтримували.
cpmjr123

Складні числа зазвичай зберігаються як два значення з плаваючою точкою, а саме їх a(реальна частина) та b(уявна частина). Процесор зазвичай не реалізує вбудовану підтримку операцій над складними числами, хоча ЦП може реалізувати прискорені вказівки множення додавання для операцій над парами значень, такими як (a b + c d) та (a b-c d).
rwong

1
Крім того, у багатьох мовах є деякі типи, поведінка яких значною мірою визначається як поведінка обертового алгебраїчного кільця (наприклад, якщо змінна типу uint16_tмістить 65535, при збільшенні вона зробить її 0). В ідеалі мови мали б чітко відокремлені типи для відображення обертових алгебраїчних кілець та цифр (дозволяючи числам, які переповнюються, перехоплюватися, дозволяючи коду легко виконувати операції над речами, які очікуються завершити).
supercat

-1

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

Уявіть, що ви хочете сортувати (довгий) масив. Наприклад в C:

int numbers[100000000];

Отже, у нас є 100 мільйонів чисел.

Якщо кожне число має довжину лише один байт (тому використовується unsigned charзамість int), то для цього потрібно 100 мільйонів байт місця.

Якщо ви використовуєте double, то це зазвичай 8 байт на число, тобто 800 мільйонів байт місця.

Тому кожен раз, коли ви оперуєте з великою кількістю об'єктів (цифри в цьому прикладі), розмір на один об'єкт (розмір на номер у цьому прикладі) дійсно має значення.

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