Ermak Опубликовано 18 января, 2021 Поделиться Опубликовано 18 января, 2021 (изменено) Всем доброго времени суток. Существует прямая проходящая через точки, например [0:0] и [150:50]. Нужно найти соответствующее значение y, например у точки x=37. Можно, как вариант, найти как отношение 37/150*50=12.33. Проблема в том, что 8-я мега и так плохо дружит с делением, а дробные числа думаю она не переживет. Есть какое то решение этой задачи, с использованием целочислительных, хоть с какой то адекватной точностью? Единственное, что пока приходит в голову - это при запуске построить все возможные целые точки ( благо их всего 100шт) и записать в EEPROM, а при включении считывать их оттуда. Но тут опять вопрос, какая скорость чтения из EEPROM? Если несколько тактов на 2 байта то сойдет, а если очень медленно, то возможно при включении читать данные из EEPROM в ОЗУ, и дальше уже ими пользоваться оттуда? Изменено 18 января, 2021 пользователем Ermak 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
colorad Опубликовано 18 января, 2021 Поделиться Опубликовано 18 января, 2021 Так попробуйте : делить на 150 = умножить на 300 и делить на два , а делить на два 8-я мега умеет - это сдвиг вправо 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
20% скидка на весь каталог электронных компонентов в ТМ Электроникс!Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!Перейти на страницу акции Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849
Ermak Опубликовано 18 января, 2021 Автор Поделиться Опубликовано 18 января, 2021 1 минуту назад, colorad сказал: : делить на 150 = умножить на 300 и делить на два , Не совсем понял, что имеете ввиду. Значения 150 и 50 приведены для примера, числа могут быть любыми. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>> Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
Стальной Опубликовано 18 января, 2021 Поделиться Опубликовано 18 января, 2021 Если прямая задаётся однократно или меняется редко, можно один раз вычислять коэффициент с точностью до целого и свободный член, а потом просто прорешивать уравнение. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
colorad Опубликовано 18 января, 2021 Поделиться Опубликовано 18 января, 2021 чет я не так сформулировал. Но смысл в том что деление на любое число заменяется делением сдвигом и умножением, а как конкретно не подскажу 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Ermak Опубликовано 18 января, 2021 Автор Поделиться Опубликовано 18 января, 2021 (изменено) 27 минут назад, Стальной сказал: вычислять коэффициент с точностью до целого и свободный член Вы коэффициент k имеете ввиду? Он может быть меньше 1. Или вы предлагаете 150/50=3. А дальше 37 / 3 = 12? Но тут опять же может быть 150/76=1. Сама прямая задается редко. 26 минут назад, colorad сказал: Но смысл в том что деление на любое число заменяется делением сдвигом и умножением, а как конкретно не подскажу Так компилятор на СИ все это сам сделает вот только быстродействие будет..... Изменено 18 января, 2021 пользователем Ermak 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Стальной Опубликовано 18 января, 2021 Поделиться Опубликовано 18 января, 2021 В случае, если коэффициент получится 0, домножать на степень двойки, а потом делить результат побитовым сдвигом. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Ermak Опубликовано 18 января, 2021 Автор Поделиться Опубликовано 18 января, 2021 (изменено) 3 минуты назад, Стальной сказал: В случае, если коэффициент получится 0, домножать на степень двойки, а потом делить результат побитовым сдвигом. Можно пример? Ато я не совсем понимаю что именно домножать, а что делить. Изменено 18 января, 2021 пользователем Ermak 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Yurkin2015 Опубликовано 18 января, 2021 Поделиться Опубликовано 18 января, 2021 (изменено) Ну, к примеру, вот такая прямая [0:0] и [150:76]. Получается формула у = х * 76 / 150. Если умножать на 76 мы умеем, то делить на 150 плохо получается. Поэтому, при сохранении коэффициента прямой, добъем знаменатель до круглого числа 256, для этого умножим числитель и знаменатель на 256/150. То есть получится у = х * 76 * (256/150) / 150 * (256 / 150) = х * 130 / 256. Вот, получается, мы число 76 заменили на 130, а 150 заменили на 256. Прямая не изменилась, а делить на 256 гораздо приятнее: деление просто заменяем на сдвиг вправо на 8, делается эта операция сдвига за пару тактов. То есть для нахождения у: сначала мы х умножаем на 130, затем результат >> 8. При изменении прямой сначала один раз долго пересчитаем коэффициент, потом уже много раз быстро умножаем со сдвигом. Изменено 18 января, 2021 пользователем Yurkin2015 2 Ссылка на комментарий Поделиться на другие сайты Поделиться
IMXO Опубликовано 18 января, 2021 Поделиться Опубликовано 18 января, 2021 Цитата Есть какое то решение этой задачи, с использованием целочислительных, хоть с какой то адекватной точностью? Y=k*X k=A/B Y=A/B*X=(A*X*216)/(B*216) y = a*x;y <<= 16;y /= b; y >>= 16; 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Yurkin2015 Опубликовано 18 января, 2021 Поделиться Опубликовано 18 января, 2021 5 minutes ago, IMXO said: y /= b; Остап Ибрагимович сказал, что бить нельзя! 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
IMXO Опубликовано 18 января, 2021 Поделиться Опубликовано 18 января, 2021 он говорил что ему нуна приемлемая точность , без использования дробей что не так? или вы думаете что в ручную получится делить быстрей чем это делает компилятор? 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Yurkin2015 Опубликовано 18 января, 2021 Поделиться Опубликовано 18 января, 2021 (изменено) @IMXO Главная идея - скорость, заменить деление на сдвиг. У Вас деление осталось в неприглядном виде. И, потом, нахрена в Вашем примере сначала сдвиг влево на 16, а в конце вправо на 16? Точность от этого не улучшится ни на грамм, только лишние телодвижения. Изменено 18 января, 2021 пользователем Yurkin2015 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Стальной Опубликовано 18 января, 2021 Поделиться Опубликовано 18 января, 2021 @Yurkin2015 если реальный коэффициент 1/2, то с домножением на 16 у нас он будет храниться как 8, без домножения - как 0. Тогда, когда потребуется число 50, например, умножить на коэффициент, то при использовании алгоритма мы получим (50*8)<<4 = 50*8/16 = 25; без алгоритма мы получим 50*0 = 0. 2 Ссылка на комментарий Поделиться на другие сайты Поделиться
Yurkin2015 Опубликовано 18 января, 2021 Поделиться Опубликовано 18 января, 2021 @Стальной Это Вы к чему написали? До сих пор никто коэффициент не вычислял и не сохранял ещё. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
colorad Опубликовано 19 января, 2021 Поделиться Опубликовано 19 января, 2021 (изменено) Х/Y = K*X/K*Y для деления сдвигом надо чтобы K*Y=256 К - определяем по таблице в зависимости от значения Y . по смыслу тоже самое, что у Yurkin2015 Изменено 19 января, 2021 пользователем colorad 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
IMXO Опубликовано 19 января, 2021 Поделиться Опубликовано 19 января, 2021 58 минут назад, Yurkin2015 сказал: Точность от этого не улучшится ни на грамм, только лишние телодвижения. вы сделали практически тоже самое, только сдвиг влево на 8 применили на коэффициент "а" с последующим делением на "b" и получили новый коэффициент на который умножаете х с последующим сдвигом вправо 8. и да надо признать ваше решение более правильное. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
солар Опубликовано 19 января, 2021 Поделиться Опубликовано 19 января, 2021 float не канает? 0 Я не раздаю удочки. Я продаю рыбу. Ссылка на комментарий Поделиться на другие сайты Поделиться
IMXO Опубликовано 19 января, 2021 Поделиться Опубликовано 19 января, 2021 где-то это уже спрашивали 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Ermak Опубликовано 19 января, 2021 Автор Поделиться Опубликовано 19 января, 2021 Спасибо за советы. После завтра буду продолжать, пока занялся железом. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Starichok Опубликовано 20 января, 2021 Поделиться Опубликовано 20 января, 2021 19.01.2021 в 01:51, Ermak сказал: Есть какое то решение этой задачи, с использованием целочислительных, хоть с какой то адекватной точностью? есть такое решение - все числа берем в 100 раз больше. тогда 37/150*50=12.33 превратится в 3700 * 5000 / 15000 = 1233. то есть, имеем результат с адекватной точностью, остается только поставить запятую (точку) в нужном месте. 5 Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду. Ссылка на комментарий Поделиться на другие сайты Поделиться
ruhi Опубликовано 20 января, 2021 Поделиться Опубликовано 20 января, 2021 (изменено) 2 часа назад, Starichok сказал: есть такое решение - все числа берем в 100 раз больше. но лучше все таки в 256 раз больше взять как написал @Yurkin2015 выше, тогда от результата надо просто последний байт отбросить, вся дробь в нем останется! Но это последнее пояснение наиболее наглядно, конечно! 2 часа назад, Starichok сказал: тогда 37/150*50=12.33 превратится в 3700 * 5000 / 15000 = 1233. Да, и достаточно один раз на 100 (на 256) умножить: 37 * 100 * 50 / 150 = 1233. Изменено 20 января, 2021 пользователем ruhi дополнил 2 Можно сделать все! Но чем больше можно, тем больше нельзя! Ссылка на комментарий Поделиться на другие сайты Поделиться
Starichok Опубликовано 21 января, 2021 Поделиться Опубликовано 21 января, 2021 в принципе, ты прав - достаточно умножить один раз на 100. хотя, гораздо удобнее все координаты держать в 100 раз больше, это избавит от лишнего умножения первого числа на 100. 0 Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду. Ссылка на комментарий Поделиться на другие сайты Поделиться
Ermak Опубликовано 21 января, 2021 Автор Поделиться Опубликовано 21 января, 2021 19.01.2021 в 01:55, Yurkin2015 сказал: Поэтому, при сохранении коэффициента прямой, добъем знаменатель до круглого числа 256, для этого умножим числитель и знаменатель на 256/150. То есть получится у = х * 76 * (256/150) / 150 * (256 / 150) = х * 130 / 256. Так чтобы получить 130 в любом случае надо будет разделить (76*256)/150. Вобщем от деления, как я понимаю, уйти не удасться... 22 часа назад, ruhi сказал: Да, и достаточно один раз на 100 (на 256) умножить: 37 * 100 * 50 / 150 = 1233. Думаю остановлюсь на этом варианте. 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
snn_krs Опубликовано 21 января, 2021 Поделиться Опубликовано 21 января, 2021 On 1/18/2021 at 11:51 PM, Ermak said: все возможные целые точки ( благо их всего 100шт) и записать в EEPROM Если памяти хватает, то это самый быстрый способ без вычислений. Делаете массив в ОЗУ с инициализацией. Компилятор сам поместит эти значения в ОЗУ. 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.