Арифметика з фіксованою точкою на мікроконтролерах


12

Часто ми використовуємо мікроконтролери для того, щоб робити свої роботи на роботах, але потрібно робити деякі обчислення у десятковій формі. Використання змінних з плаваючою комою відбувається дуже повільно, оскільки автоматична бібліотека з плаваючою точкою автоматично включається (якщо у вас немає мікроконтролера високого класу). Тому ми зазвичай використовуємо арифметику з фіксованою точкою.

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

Я реалізував функцію atan2 з фіксованою точкою, але, оскільки я намагався видавити кожну останню краплю з обмеженою точністю (16 біт), я часто міняв би визначення десяткової крапки, і це змінюватиметься, коли я її налаштовував. Крім того, у мене були б деякі константи, як квазі-таблиця пошуку, яка сама десь має на увазі десяткове місце.

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


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

1
@Jakob - Зауважте, що обидва ці питання були закриті як неконструктивні.
Марк Бут

1
Це те, що зробить C ++ дуже корисним для вбудованих систем. Шаблони автоматично генерують правильний та оптимальний код.
Rocketmagnet

1
Чи можу я ознайомитися з вашою функцією атану? Я намагаюся вирішити проблему перетворення з плаваючою в фіксовану точку в своєму академічному дослідженні, і я був би радий розірвати це.
Джо Хасс

1
@ronalchn Частини Arduino (з мікро AVR) мови реалізуються в C ++. Також є бібліотека AVR C ++ . І ця нитка, на якій компілятори використовувати.
embedded.kyle

Відповіді:


7

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

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


Це майже напевно можливо зробити за допомогою шаблонів C ++.
Rocketmagnet

Я фактично працюю над чимось таким, як ваш коментар "було б добре, якби ...". Це плагін для gcc, який перетворює код С з плаваючою комою у фіксовану точку, оптимізуючи всі місця бінарних точок на цьому шляху. У мене є документ, поданий до журналу ACM, та інший у процесі підготовки. Якщо у вас є код C для функції atan, я був би радий спробувати його ... Я міг би повернути вам код C, який використовує цілі змінні та робить усі речі з фіксованою точкою.
Джо Хасс

+1 для набагато повнішої відповіді, ніж моя. Я редагував посилання в моєму, щоб включити посилання на місце, щоб запросити вихідний код, щоб вирішити коментар Марка Бута. Ви можете також оновити своє посилання. Я б це зробив сам, але запропонована редакція стоїть у черзі і блокує мене.
embedded.kyle

1
@Rocketmagnet Це, безумовно, можна реалізувати фіксовані точки за допомогою шаблонів, див. FixedPoints (відмова від відповідальності: я написав це, і він все ще дуже «молодий»).
Фарап

gcc посилання "a" розірвано
Lesto

2

Я використовував бібліотеку TI IQMath для реалізації віртуальної плаваючої точки на своїх DSP з фіксованою точкою.

Технічна бібліотека Texas Instruments TMS320C28x IQmath - це колекція високооптимізованих і високоточних математичних функцій для програмістів C / C ++ для безперебійного портування алгоритму з плаваючою комою у код з фіксованою точкою на пристроях TMS320C28x. Ці процедури зазвичай використовуються в обчислювально інтенсивних додатках у режимі реального часу, де оптимальна швидкість виконання та висока точність є критичними. Використовуючи ці підпрограми, ви можете досягти швидкості виконання значно швидше, ніж еквівалентний код, написаний на стандартній мові ANSI C. Крім того, надаючи готові до використання функції високої точності, бібліотека TI IQmath може значно скоротити час розробки додатків DSP.

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


@downvoter Care прокоментувати те, що було не так у моїй відповіді?
embedded.kyle

+1: Ця бібліотека краща за те, що він зараз використовує ("просто використовувати ціле число"). Це не робить все, про що було задано первісне запитання, але я думаю, що така відповідь (корисна, але не повне рішення) не заслуговує на ослаблення, якщо тільки не існує повного рішення (що я сумніваюся в цьому випадку ).
Девід Кері

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

@MarkBooth Я змінив посилання з бібліотеки C28x на бібліотеку C64x. Якщо ви перейдете за цим посиланням, ви можете запитати вихідний код. Щоб отримати доступ, вам потрібна електронна адреса компанії або університету. Ще вільна, як у пиві та у виступі. Вам просто потрібно підняти руку і чекати, коли вас зателефонують, перш ніж ви зможете поговорити. Трохи дратує, але коли ви маєте вихідний код, його можна адаптувати до будь-якого процесора, який вам подобається.
embedded.kyle

Спасибі @ embedded.kyle вихідний код, безумовно, кращий, ніж лише двійковий, але все ще мало загальний, якщо ліцензія дозволяє використовувати його обмеженими способами. За даними сторінки бібліотеки програмного забезпечення C6x, це джерело випускається лише під комерційною ліцензією TI , що майже напевно не є вільним, як у мовленні .
Марк Бут

1

Існує ряд реалізацій (жодних бібліотек, про які я одразу знаю) бінарного масштабування (він же B-масштабування)

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

Я використовував B-масштабування в асемблері на оборонних проектах, навіть на найменших процесорах, тому можна підтвердити його придатність для чого-небудь іншого ...


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

0

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

atancosππ

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

struct num
{
    uint16_t number;
    uint16_t decimal_point;
};

де numberціле число і decimal_pointговорить де десяткова крапка, ви можете зберігати його так:

struct num
{
    uint16_t integer;
    uint16_t fraction;
};

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


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

Я не маю на увазі запам'ятовування, як це зберігається в змінній, я маю на увазі запам'ятовування, як і я пам'ятаю, як інтерпретувати результат (знаючи, де знаходиться десяткова крапка)
ronalchn

@ronalchn, я бачу. Ви мали на увазі щось на кшталт а #define, правда? Я думав, що ви насправді зберігаєте його, і він може змінюватись залежно від того, наскільки велика чи мала ваша кількість.
Шахбаз

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