Code Monkey home page Code Monkey logo

fixed's Introduction

latest PIO Foo Foo Foo

Foo

fixed

Реализация вычислений с фиксированной точкой для Arduino

Совместимость

Совместима со всеми Arduino платформами (используются Arduino-функции)

Содержание

Установка

  • Библиотеку можно найти по названию fixed и установить через менеджер библиотек в:
    • Arduino IDE
    • Arduino IDE v2
    • PlatformIO
  • Скачать библиотеку .zip архивом для ручной установки:
    • Распаковать и положить в C:\Program Files (x86)\Arduino\libraries (Windows x64)
    • Распаковать и положить в C:\Program Files\Arduino\libraries (Windows x32)
    • Распаковать и положить в Документы/Arduino/libraries/
    • (Arduino IDE) автоматическая установка из .zip: Скетч/Подключить библиотеку/Добавить .ZIP библиотеку… и указать скачанный архив
  • Читай более подробную инструкцию по установке библиотек здесь

Обновление

  • Рекомендую всегда обновлять библиотеку: в новых версиях исправляются ошибки и баги, а также проводится оптимизация и добавляются новые фичи
  • Через менеджер библиотек IDE: найти библиотеку как при установке и нажать "Обновить"
  • Вручную: удалить папку со старой версией, а затем положить на её место новую. "Замену" делать нельзя: иногда в новых версиях удаляются файлы, которые останутся при замене и могут привести к ошибкам!

Инициализация

Нет

Использование

См. пример

Пример

#include <fixed.h>

void setup() {
  Serial.begin(9600);
  
  volatile fixed value(3, 100);    // 0.03
  value *= 100;           // 3.0 
  value /= 2;             // 1.5
  value += toFix(3, 10);  // 1.8 (+0.3) 
  Serial.println(value.toFloat());
  // 1730/188
  
  /*
  volatile float value = 0.03;
  value *= 100;           // 3.0 
  value /= 2;             // 1.5
  value += 0.3;           // 1.8 (+0.3) 
  Serial.println(value);
  // 3046/200
  */
  
  //Serial.println((int32_t&)value);  // вывод fixed числа
  //Serial.println(value.fix);        // вывод fixed числа
  //Serial.println(value.toInt());      // перевод в int
  //Serial.println(value.toFloat());  // перевод в float
  //Serial.println(expandFix(value)); // раскрывающий макрос
}

void loop() {
}

Версии

  • v1.0

Баги и обратная связь

При нахождении багов создавайте Issue, а лучше сразу пишите на почту [email protected]
Библиотека открыта для доработки и ваших Pull Request'ов!

При сообщении о багах или некорректной работе библиотеки нужно обязательно указывать:

  • Версия библиотеки
  • Какой используется МК
  • Версия SDK (для ESP)
  • Версия Arduino IDE
  • Корректно ли работают ли встроенные примеры, в которых используются функции и конструкции, приводящие к багу в вашем коде
  • Какой код загружался, какая работа от него ожидалась и как он работает в реальности
  • В идеале приложить минимальный код, в котором наблюдается баг. Не полотно из тысячи строк, а минимальный код

fixed's People

Contributors

alexgyver avatar gyverlibs avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

artemiykolobov

fixed's Issues

Баг при умножении и делении fixed на fixed.

Баг при умножении и делении fixed на fixed

В процессе реализации одного проекта мне понадобилась ( понял я это по Вашей же наводке из статьи) библиотека для использования натуральных чисел с фиксированной точкой. Так как о Bашей библиотеке я ничего не знал(или её тогда и не было), я начал писать свою. Позже, после написания своей, я обнаружил данную библиотеку. Объективно - Ваша библиотека наглядней, проще, и занимает меньше ресурсов, чем моя. (Одна, но не единственная из причин того - моё желание реализовать функцию to_string в обход использования float).

Однако при тесте Вашей библиотеки я нашёл некоторые ошибки:

  • библиотека fixed некорректно считает операции умножения и деления fixed с fixed:
#include <fixed.h>
void setup() {
 Serial.begin(9600);
 fixed value (3, 10);            // 0.3
 fixed value2(5, 10);            // 0.5
 fixed value3;
 value3 = value * value2;        // 0.15
 Serial.println(value3.toFloat());
 value3 = value / value2;        // 0.6
 Serial.println(value3.toFloat());
 void loop() {
 }

Вывод на порт:
2457.50
0.00
Всё дело в том, что строчки:

 82: fixed& operator *= (fixed val) {fix *= val.fix; return *this;}
100: fixed& operator /= (fixed val) {fix /= val.fix; return *this;}

не учитывают, некоторых арифметических особенностей.
Представим значение fixed A, хранящее в поле fix значение X, мысленно поделённое на 2^N, где N=12.
Получим, что A = X/(2^N).
Тогда, для аддитивных операторов, при сложении A и B:
A+-B= Xa/(2^N)+-Xb/(2^N)=(Xa+-Xb)/(2^N)
Таким образом, для того, чтобы сложить A и B, необходимо просто сложить их поля fix (Xa+Xb)
Однако, при мультипликативных операторах:
A*B=(Xa/(2^N))*(Xb/(2^N))=(Xa*Xb)/((2^N)*(2^N))
То есть, при перемножении (Xa*Xb) мы получим не A*B, а A*B/(2^N), и, чтобы получить искомое, необходимо Xa*Xb поделить на (2^N)
Аналогично при делении:
A/B=(Xa/(2^N))/(Xb/(2^N))=(Xa*(2^N))/(Xb*(2^N))=Xa/Xb
Тут уже не хватает 2^N.
Следовательно, наша поправка:

  82: fixed& operator *= (fixed val) {fix =(fix * val.fix) / FIX_MUL; return *this;}
 100: fixed& operator /= (fixed val) {fix = FIX_INT(fix) / val.fix ; return *this;}

И на выходе мы имеем закономерные
0.15
0.60

А ещё я бы Вам предложил (это не совет, а просто предложение, так как скорее всего я знаю C++ хуже Вас) использовать шаблоны типа:
T template <class TYPE> для сокращения количества текста в исходном коде, т.е. приведя пример:

    fixed& operator += (fixed val) {fix += val.fix; return *this;}
    fixed& operator += (uint32_t val) {fix += FIX_UINT(val); return *this;}
    fixed& operator += (int32_t val) {fix += FIX_INT(val); return *this;}
    fixed& operator += (uint16_t val) {fix += FIX_UINT(val); return *this;}
    fixed& operator += (int16_t val) {fix += FIX_INT(val); return *this;}
    fixed& operator += (uint8_t val) {fix += FIX_UINT(val); return *this;}
    fixed& operator += (int8_t val) {fix += FIX_INT(val); return *this;}
    fixed& operator += (double val) {fix += FIX_FLOAT(val); return *this;}

заменяем на:

#define T template <class TYPE>
	fixed& operator += (fixed val) {fix += val.fix; return *this;}
T	fixed& operator += (TYPE val) {fix += FIX_INT(val); return *this;}

И выкидываем FIX_UINT, так как я предполагаю, что компилятор уж за нас сообразит, где упростить умножение сдвигом.

Кстати, объявление переменной, как volatile, при умножении fixed на fixed, возвращает ошибку:
error: binding reference of type 'fixed&' to 'volatile fixed' discards qualifiers
Как с этим бороться - я пока не понял.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.