Тип float
Числа з плаваючою комою використовують формат IEEE (Інституту інженерів з електротехніки та електроніки). Значення з одиночною точністю та типом float мають 4 байти, складаються з біта знака, 8-розрядної двійкової експоненти excess-127 та 23-бітної мантиси. Мантісса є числом від 1,0 до 2,0. Оскільки біт високого порядку мантиси завжди дорівнює 1, він зберігається в числе. Це подання забезпечує для типу float діапазон приблизно від 3,4E-38 до 3,4E +38.
Можна оголосити змінні як тип float або double в залежності від потреб програми. Основні відмінності між двома типами значення полягають у представленій ними значущості, необхідних ресурсах зберігання та діапазоні. У наступній таблиці показано зв'язок між значимістю та вимогами до зберігання.
Типи з плаваючою комою
| Тип |
Значні цифри |
Число байтів |
| з плаваючою комою |
6–7 |
4 |
| подвійний точності |
15–16 |
8 |
Змінні з плаваючою комою представлені мантисою, що містить значення числа, та експонентою, яка містить порядок зростання числа.
У наступній таблиці показано кількість бітів, виділених мантисі та експоненті для кожного типу з плаваючою комою. Найбільш значущий біт будь-якого типу float або double завжди біт знака. Якщо вона дорівнює 1, число вважається негативним; в іншому випадку - позитивним.
Довжина експонент та мантис
| Тип |
Довжина експонентів |
Довжина мантиси |
| з плаваючою комою |
8 біт |
23 біта |
| подвійний точності |
11 біт |
52 біта |
Оскільки експоненти зберігаються у формі без знака, експоненти зміщені половину свого можливого значення. Для типу float зсув становить 127; для типу double це 1023. Можна обчислити фактичне значення експоненти, віднімаючи значення усунення значення експоненти.
Мантіса зберігається у вигляді бінарної частки, яка більша або дорівнює 1 і менше 2. Для типів float і double в мантисі мається на увазі наявність початкового 1 в найбільш значущій бітовій позиції, тому фактично довжина мантис становить 24 і 53 біт відповідно, навіть якщо найбільш значущий біт ніколи не зберігається у пам'яті.
Замість описаного методу зберігання пакет значень з плаваючою комою може зберігати двійкові числа з плаваючою комою як денормалізовані числа. Денормалізовані числа — це ненульові числа з плаваючою комою та зарезервованими значеннями експонент, у яких найбільш значущий біт мантиси дорівнює 0. Використовуючи денормалізований формат, можна розширити діапазон числа з плаваючою комою на шкоду точності. Неможливо контролювати, в якій формі буде представлено число з плаваючою комою – нормалізованою чи денормалізованою. Пакет значень із плаваючою комою визначає подання. У пакеті значень із плаваючою комою ніколи не використовується денормалізована форма. Виняток становлять випадки, коли експонента стає менше, ніж мінімальне значення, яке може бути представлене у нормалізованій формі.
У наступній таблиці показано мінімальне та максимальне значення, яке можна зберегти в змінних кожного типу з плаваючою комою. Значення, зазначені в цій таблиці, застосовуються лише до нормалізованих чисел з плаваючою комою; денормалізовані числа з плаваючою комою мають менше мінімальне значення. Зверніть увагу, що номери, збережені в регістрах 80x87, завжди представлені у 80-розрядній нормалізованій формі; при збереженні в 32- або 64-розрядних змінних з плаваючою комою числа можуть бути представлені тільки в ненормалізованій формі (змінні типи float і long).
Діапазон типів з плаваючою комою
| Тип |
Мінімальне значення |
Максимальне значення |
| з плаваючою комою |
1,175494351 E – 38 |
3,402823466 E + 38 |
| подвійний точності |
2,2250738585072014 E – 308 |
1,7976931348623158 E + 308 |
Якщо точність менш важлива, ніж розмір даних, що зберігається, має сенс використовувати тип float для змінних з плаваючою комою. І навпаки, якщо точність – найважливіший критерій, використовуйте тип double.
Рівень змінних з плаваючою комою можна підвищити до більшої значимості (перетворення типу float в тип double). Підвищення рівня часто відбувається при виконанні арифметичних дій зі змінними плаваючими типами. Ця арифметична дія завжди виконується на тому ж рівні точності, що й змінна з найвищим рівнем точності. Наприклад, проаналізуйте об'яви таких типів.
float f_short; double f_long; long double f_longer; f_short = f_short * f_long;
У попередньому прикладі рівень змінної f_short підвищується до типу double, а потім змінна множиться на f_long; потім результат округляється до типу float і надається об'єкту f_short .
У наступному прикладі (з використанням оголошень із попереднього прикладу) арифметична операція виконується на рівні точності змінної типу float (32-розрядної). Рівень результату потім підвищується до рівня double.
f_longer = f_short * f_short;
C++: Типи даних з плаваючою точкою
Цілочисленні типи відмінно підходять для підрахунку цілих чисел, але іноді нам потрібно зберігати дуже великі числа чи числа з дробовиною. Змінна типу з плаваючою точкою – це змінна, яка може містити дійсне число, наприклад, 4320,0, -3,33 або 0,01226. Назва плаваюча точка вказує на те, що десяткова точка може плавати, тобто вона може підтримувати змінну кількість цифр до і після себе.
Існує три різних типи даних з плаваючою точкою: float, double та long double. Як і у випадку з цілими числами, C++ не визначає фактичних розмірів цих типів, але гарантує мінімальні розміри:
- float – повинен мати як мінімум 32-біти та гарантувати мінімум 6 значущих цифр
- double – 48-біт та бути не менше float. Гарантує 15 цифр
- long double – як мінімум 80 бітів та 18-значних цифр
Типи даних з плаваючою точкою завжди йдуть зі знаком, тобто можуть містити позитивні та негативні значення.
Нижче наведено приклади визначення змінних з плаваючою точкою:
float f_num; double d_num; long double ld_num;
Ви могли помітити, що в імені змінної використовується префікс - це робити не обов'язково, але це допомагає зрозуміти змінна кого типу зараз використовується.
При ініціалізації змінних такого типу завжди вмикайте хоча б один знак після десяткової точки, навіть якщо це нуль. Так компілятор розумітиме, що змінна належить до речового типу.
double d_num <5.0>; float f_num <5.0f>;
За замовчуванням літерали з плаваючою точкою мають тип double. Суфікс f використовується для позначення літералу типу float.
Ви могли помітити, що у коді вище ініціалізація проводиться не через оператор присвоєння = , а за допомогою нотації <5.0>. Це спискова ініціалізація, вона прийшла в мову з 11 стандарту і має одну перевагу:
int num; num = 3.14; std::cout 3
У коді вище ми намагаємося зберегти в цілісну змінну речове число.Така програма скомпілюється і працюватиме, але у числа ми втратимо всю речову частину.
Якщо застосувати спискову ініціалізацію, отримаємо помилку компіляції:
int num <3.14>; // помилка int count; count = <3.14>; // помилка
Розглянемо таку програму:
int main() < float f_num = < 10.0/3.0 >; double d_num = <10.0/3.0>; std::cout
Зверніть увагу, що кожне з надрукованих значень має лише 6 цифр. Це стандартна поведінка об'єкта cout , але ми можемо перевизначити цю поведінку та підвищити точність:
#include #include // збільшення точності int main() < std::cout ; double d_num = <10.0/3.0>; std::cout
3.333333253860474 3.333333333333333
Видно, що число float визначено не точно і містить помилки, оскільки тип float гарантує нам лише шість цифр.
Існує дві спеціальні категорії чисел з плаваючою точкою. Перша - Inf, яка представляє нескінченність. Inf може бути позитивною чи негативною. Друга - NaN, що означає Not a Number - не число. Існує кілька різних типів NaN. NaN та Inf доступні лише в тому випадку, якщо компілятор для чисел з плаваючою точкою використовує певний формат. Якщо використовується інший формат, наступний код призводить до невизначеної поведінки.
#include int main() < double zero < 0.0 >; double pos_inf <5.0/zero>; // позитивна нескінченність std::cout; // негативна нескінченність std::cout; // не число (математично невірно) std::cout
Завдання
Напишіть програму, яка розраховує, скільки кілометрів проїде автомобіль на повному баку. Нехай обсяг бака буде 43 літри, а витрата 8.8 л на 10 км. Результат виведіть на екран.
Якщо ви зайшли в глухий кут, то саме час поставити питання в «Обговореннях».Як правильно поставити запитання:
- Обов'язково докладіть виведення тестів, без нього практично неможливо зрозуміти, що не так, навіть якщо ви покажете свій код. Програмісти погано виконують код у голові, але за помилкою майже завжди зрозуміло, куди дивитися.
Тести влаштовані таким чином, що вони перевіряють рішення різними способами та на різних даних. Часто рішення працює з одними вхідними даними, але з іншими. Щоб розібратися з цим моментом, вивчіть вкладку «Тести» та уважно подивіться на виведення помилок, у якому є підказки.
Це нормально 🙆, у програмуванні одне завдання можна виконати безліччю способів. Якщо ваш код пройшов перевірку, він відповідає умовам завдання.
У поодиноких випадках буває, що рішення підігнано під тести, але це видно відразу.
Створювати навчальні матеріали, зрозумілі всім без винятку, досить складно. Ми дуже намагаємося, але завжди є що покращувати. Якщо ви зустріли матеріал, який вам незрозумілий, напишіть проблему в «Обговореннях». Ідеально, якщо ви сформулюєте незрозумілі моменти як запитань. Зазвичай нам потрібно кілька днів для внесення поправок.
До речі, ви також можете брати участь у покращенні курсів: унизу є посилання на вихідний код уроків, який можна правити прямо з браузера.