Перейти к содержанию

Как Отдельно Изменять Целую И Дробную Часть В Параметре Double


Рекомендуемые сообщения

Добрый день. Работаю над проектом где есть два микроконтроллера PIC, EEPROM и дисплей с клавиатурой. На одном контроллере реализовано меню настроек где есть параметр с десятичной точкой(переменная double). Этот параметр сохраняется в EEPROM а потом читается другим контроллером для использования в алгоритме управления. Соответственно, нужно как то получать доступ отдельно к целой и дробной частям числа и изменять их как будто это два разных числа.

Пробовал использовать modf() для получения целой и дробной части, менять их, а потом через sprintf() обьединять их в строку и далее через atof() получать обратно double, но такой способ использует непозволительно много памяти.

Еще более оптимальный способ это хранить и изменять целую и дробную части как два однобайтовых числа, а второй контроллер уже будет сам "сшивать их" в переменную double как написано выше. Но это тоже как то не красиво.

Подскажите какие еще есть способы "экономно" сделать это на МК про которые я еще не знаю? Может как то оптимизировать?

Пишу на Си (компилятор XC8).

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Этот параметр сохраняется в EEPROM а потом читается другим контроллером
Тут немного не понятно, как у второго контроллера будет организован доступ к ЕЕПРОМ первого ?

А так - через прямой доступ к одной области памяти, обоими кусками кода.

Зачем переменную раскладывать, а потом обратно складывать, если можно её просто копировать побайтово, один в один ?

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Тут немного не понятно, как у второго контроллера будет организован доступ к ЕЕПРОМ первого ?

EEPROM внешняя общая. Обмен с контроллерами по i2c

Зачем переменную раскладывать, а потом обратно складывать, если можно её просто копировать побайтово, один в один ?

Тут мне не понятно. Как это возможно если компилятор Си хранит double в 3 байтах? Как определить в каких байтах закодирована целая часть, а каких дробная?

Изменено пользователем Rapture
Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Точно ли необходимо использование медленного и громоздкого double вместо чисел с фиксированной точкой? Кстати, объем double либо 4, либо 8 байт, в зависимости от компилятора, но не 3.

Формат чисел с плавающей точкой достаточно подробно расписан в интернете.

Пробовал использовать modf() для получения целой и дробной части, менять их, а потом через sprintf() обьединять их в строку и далее через atof() получать обратно double, но

такой способ использует непозволительно много памяти.

А просто сложить их без извращений с переводом в строку не получается?

double val = 12.34;
double tr,fr;
fr = modf(val, &tr);
// tr = 12 ; fr = 0.34
val = tr+fr;
// val = 12.34

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

Ссылка на комментарий
Поделиться на другие сайты

Тут мне не понятно. Как это возможно если компилятор Си хранит double в 3 байтах?
Да хоть в 33. Эти байты и читайте в такую же double переменную. В ней и будет лежать её значение.
Как определить в каких байтах закодирована целая часть, а каких дробная?
Интересно, это Вы у нас спрашиваете ? Это мы должны у Вас спросить, как Вы там их в ЕЕПРОМ укладываете.

Кстати, вопрос, а как Вы их туда сохраняете ? В каком виде и в каком порядке ?

Ссылка на комментарий
Поделиться на другие сайты

Кстати, объем double либо 4, либо 8 байт, в зависимости от компилятора, но не 3.

В XC8 есть "урезаные" версии float и double, занимающий 3 байта.

double val = 12.34;
double tr,fr;
fr = modf(val, &tr);
// tr = 12 ; fr = 0.34
val = tr+fr;
// val = 12.34

Спасибо. Не догадался)

Кстати, вопрос, а как Вы их туда сохраняете ? В каком виде и в каком порядке ?

Переменная double обьявлена как union. Соответсвенно могу раскладывать и складывать ее по байтам.

Хорошо, если на форуме найдутся такие люди которые уже делали такой функционал и помогут советом, чтобы я не изобретал велосипеды... ))

Ссылка на комментарий
Поделиться на другие сайты

Соответсвенно могу раскладывать и складывать ее по байтам.
Дак вот Вам и ответ.

Один проц раскладывает и записывает в епром, другой читает и обратно собирает. В результате во втором проце получаем переменную с значением, равным записанной переменной первого проца.

Имеем только операции с манипуляциями байтов. Никаких бешеных вычислений.

Ссылка на комментарий
Поделиться на другие сайты

Один проц раскладывает и записывает в епром, другой читает и обратно собирает. В результате во втором проце получаем переменную с значением, равным записанной переменной первого проца.

Мой вопрос не в том как передать переменную, а в том как в меню на экранчике реализовать настройку отдельно целой и отдельно дробной части, при этом красиво и эффективно, не используя массу памяти. Такое ведь наверняка делали.

Изменено пользователем Rapture
Ссылка на комментарий
Поделиться на другие сайты

Про экран и про меню не было ни слова.

Я отталкивался вот от этих Ваших действий :

Пробовал использовать modf() для получения целой и дробной части, менять их, а потом через sprintf() обьединять их в строку и далее через atof() получать обратно double, но такой способ использует непозволительно много памяти.
В которых Вы из double переводите обратно в double, только через ж... Китай.

А так, раскладывайте переменную через modf, затем обычныой арифметикой обратно складывайте.

Но, как уже выше сказали, стоит ли использовать плавающую точку ? Может присмотреться к фиксированной ? И уже изначально хранить целое значение и дробное, только в целочисленной переменной.

Ссылка на комментарий
Поделиться на другие сайты

Спасибо за советы. Попробую и так и так. Только пока что с трудом понимаю как реализовать фиксированую точку, как разделить целочисленную переменную на две части и отдельно их редактировать, при этом в меню при редактировании должна отображатся запятая между частями. И как потом сшить это и использовать в формуле в качестве вещественного числа? (суть вопроса осталась та же)

Покажите на примерах пожалуйста

Ссылка на комментарий
Поделиться на другие сайты

Определитесь с максимальным значением. Определитесь с разрешением дробной части. Отсюда выберите тип целочисленной переменной.

Например, максимальное значение = 1000,00, разрешение = 0,01. Получаем фиксированную точку во втором разряде.

Максимальное значение для целочисленной переменной = 100000. Тут только 4-х байтная переменная подойдёт, т.б. long.

Далее, чтобы прибавить к нашему виртуальному значению 0,01 - просто прибавляем к переменной единицу. Если нужно прибавить 0,1 - прибавляем 10. Для единицы - 100. Это что касается математики с числом.

Что касается разложения на целые и дробные, для вывода - обычная арифметика. Деление на 100 (виртуальная единица) даст целые значения виртуального числа, остаток от деления - дробную часть (виртуальных, умноженных на 0,01).

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...