Типи з плаваючою комою фіксованого розміру


91

У заголовках stdint.h(C99), boost / cstdint.hpp та cstdint(C ++ 0x) серед іншого є тип int32_t.

Чи існують подібні типи з плаваючою комою фіксованого розміру? Щось на зразок float32_t?


4
Навіщо вам щось подібне?
AraK

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

5
@mobrule: Якщо вам просто потрібно знати, який розмір, ви використовуєте sizeofоператор. Такий тип був би корисний, коли алгоритм вимагає, щоб він мав відомий конкретний розмір.
Стівен Канон

6
@Stephen Canon - так, коли ви хочете гарантувати, який розмір. Скажімо, екземпляр вашої структури даних вміститься в 64 біти і може бути переданий за значенням до якоїсь зовнішньої бібліотеки.
моб

6
@StephenCanon Розглянемо міжплатформну бібліотеку серіалізації. Як можна sizeofвикористати для вирішення проблеми послідовного маршування та демаршування плаваючих типів?
Kyle Strand

Відповіді:


47

На сьогодні нічого подібного не існує в стандартах С або С ++. Насправді навіть немає гарантії, що floatце буде двійковий формат із плаваючою комою взагалі.

Деякі компілятори гарантують, що floatтип буде 32-бітовим бінарним форматом IEEE-754. Деякі ні. Насправді floatце singleтип IEEE-754 на більшості невбудованих платформ, хоча застосовуються звичайні застереження щодо деяких компіляторів, які оцінюють вирази в більш широкому форматі.

Існує робоча група, яка обговорює питання додавання прив’язок мови C для перегляду IEEE-754 у 2008 році, яка може розглянути можливість рекомендувати додати такий typedef. Якби це було додано до C, я думаю, що стандарт C ++ наслідував би його ... врешті-решт.


3
Незалежно від IEEE-754 чи ні, він все одно не запобіжить проблемам перенесення ендіан.
Mark B

1
@Pietro: зміна мови не вплине на сумісність апаратного забезпечення, це лише унеможливить відповідність певного обладнання. Яким чином IEEE FP гарантує перенесення портативності?
Potatoswatter

1
@Potatoswatter: Це заохочувало б виробників обладнання пропонувати сумісні рішення. Якщо частина a підтримує стандарт C, не потребуючи програмного злому бібліотеки, а частина b - ні, це ринкова перевага для частини a.
Стівен Канон

2
@Potatoswatter: (Майже) ніхто не дбає про швидкість роботи обладнання. Ми дбаємо про швидкість програмного забезпечення, що працює на апаратному забезпеченні. Програмне забезпечення може бути швидшим, якщо обладнання, на якому воно працює, відповідає стандартам, і програмне забезпечення не потребує виявлення та виправлення 15 різних особливих випадків, залежно від того, на якій платформі воно працює.
Стівен Канон

8
Як на Землі ви могли б отримати кращу портативність, запобігаючи компіляції коду в ряді нішевих архітектур? Або ви покладаєтесь на плаваючу форму, яка є IEEE, і в цьому випадку ваш код вже буде працювати на кожній реалізації, сумісній з IEEE, і ні на що інше, або ви цього не робите, і в цьому випадку ваш код буде працювати в більш широкому діапазоні систем. Якби C ++ гарантував відповідність IEEE, ваш код магічно не став би більш портативним, ви просто виключили б, що він коли-небудь міг працювати на тих невідповідних архітектурах. Ваша логіка повністю відстала.
jalf

30

Якщо ви хочете дізнатись, чи floatє ваш 32-розрядний тип IEEE, перевірте std::numeric_limits<float>::is_iec559. Це константа часу компіляції, а не функція.

Якщо ви хочете бути більш захищеними від кулі, також std::numeric_limits<float>::digitsпереконайтесь, що вони не підступно використовують стандартну подвійну точність IEEE для float. Має бути 24.

Коли справа стосується long double, важливіше це перевірити, digitsоскільки існує кілька форматів IEEE, якими це може бути обґрунтовано: 128 біт (цифри = 113) або 80 бітів (цифри = 64).

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


long doubleФормат на OS X (32-біт і 64-біт Intel) в точності IEEE-754 з подвійною розширений формат зберігається в мало-Endian порядку. Нічого забавного в цьому взагалі. Байти 0-7 містять поле значущості та байти 8 та 9 містять поля експоненти та знака.
Стівен Канон

@Stephen: це хороша новина: v). Чи це узгоджується з номерами, які я розмістив?
Potatoswatter

1
Пам'ятайте, що подвійний розширений (на відміну від інших 754 форматів) має явний провідний біт значення, тому 5.0Lмає значення a000000000000000. Його неупереджений показник дорівнює +2, а подвійне розширене зміщення показника дорівнює 3fff, тому зміщений показник для 5.0L є 4001. Фактичним шаблоном байтів при зберіганні в порядку мало-ендіанського є 00 00 00 00 00 00 00 a0 01 40, і якщо ви розглянете це як два мало-ендіанські 64-розрядні цілі числа, ви побачите саме те, що ви спостерігали.
Стівен Канон

(*) подвійне розширення, як це впроваджено Intel в апаратне забезпечення, тобто. Подвійний розширений формат насправді не закріплений так, як інші два основні формати IEEE-754 (1985).
Стівен Канон

@Stephen: Я майже впевнений, що 4001в little-endian - 01 40 00 00 ...якщо нічого іншого, найменш значущий байт стоїть на першому місці. Я справді очікую, що послідовність a0 01 40з’явиться десь у номері (якщо вони виконували лише обертання), але, думаю, ви не пояснили, чому, a0і 01 40перебуваєте в абсолютно окремих половинах.
Potatoswatter

18

Якщо ви вважаєте, що наявність typedefs, таких як float32_t та float64_t, непрактично з будь-яких причин, ви повинні бути занадто звичними до своєї знайомої ОС, компілятора, щоб ви не могли занадто виглядати поза своїм маленьким гніздом.

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

Мені особисто незручно користуватися поплавками та дублями, якщо я точно не знаю, скільки бітів вони на моїй платформі. Навіть більше, якщо я хочу перенести їх на іншу платформу через якийсь канал зв'язку.


"Мені особисто незручно користуватися плаваючими та дублями, якщо я точно не знаю, скільки бітів вони є на моїй платформі. Навіть більше, якщо я хочу перенести їх на іншу платформу через якийсь канал зв'язку". - Ви маєте на увазі, що використовуєте формати текстових файлів? З цим є недолік розміру файлу: 32 плаваючій системі потрібно 4 байти; вони у текстовій формі можуть представляти лише чотирицифрове число ...
П'єтро

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