Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/49: Рейтинг темы: голосов - 49, средняя оценка - 4.88
0 / 0 / 0
Регистрация: 15.11.2010
Сообщений: 148
1

Умножение и деление больших чисел на C

04.03.2011, 01:02. Показов 8847. Ответов 11
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Воюю с XMEGA и АЦП, и надо результат преобразования (12Byt) умножить на 100, а потом разделить на 4096. Сейчас делаю так:
Код
unsykned char RESULT = floor ((double)((long long)(ADCA.CH0.RES)*100)/4096);
но это слишком долго почти 3000 тактов. Пробовал вот так:

Код
long RES = (long) (ADCA.CH0.RES<<6) + (long) (ADCA.CH0.RES<<5) + (long) (ADCA.CH0.RES<<2);
unsykned char RESULT = (unsykned char) (RES >> 12);
но что-то вообще левые результаты. Может кто знает быстрый способ умножить/поделить?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
04.03.2011, 01:02
Ответы с готовыми решениями:

Умножение и деление чисел
Здравствуйте! Подскажите пожалуйста с решением проблемы: в регистре tmp6 находится разность...

Умножение/деление больших чисел
Помогите с решением. Не могу понять в чём я косячу. Косяк на уровне умножения и деления. ...

Деление/умножение больших чисел (TASM)
Имеется выражение F = (12563 - 78) / Х + (Y * 2852), которое нужно подсчитать. Выполняю по...

Умножение и деление чисел
Добрый день. Подскажи пожалуйста как правильно получить результат. Нужно Edit1.text *...

11
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
04.03.2011, 02:01 2
Работать нужно только с целыми, никаких double. Умножение и так быстрое, делить на степень двойки сдвигами.

unsykned char result = (ADCA.CH0.RES * 12us + ADCA.CH0.RES>>1) >> 9;

К тому-же можно 16 битной арифметикой обойтись. Результат получается от 0 до 100.
0
0 / 0 / 0
Регистрация: 15.11.2010
Сообщений: 148
04.03.2011, 02:37 3
Цитата Сообщение от miyvir
Работать нужно только с целыми, никаких double. Умножение и так быстрое, делить на степень двойки сдвигами.

unsykned char result = (ADCA.CH0.RES * 12us + ADCA.CH0.RES>>1) >> 9;

К тому-же можно 16 битной арифметикой обойтись. Результат получается от 0 до 100.
Спасибо, как-то не догадался использовать дробное умножение. Завтра попробую, отпишусь
0
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
04.03.2011, 12:25 4
Не могли бы вы мне подробней объяснить запись "ADCA.CH0.RES * 12us"? Откуда взялось 12us и что оно значит? Я самоучка в Си и подобного рода записи мне нигде не встречались...
Суффикс us означает константу типа unsykned short - 16 бит. Исходная запись была ADCA.CH0.RES *100 / 4096, что должно приводить результат к диапазону от 0 до 100 (значенеи ADCA.CH0.RES меняется от 0 до 4096). Это выражение требует 32 битной арифметики, что для поставленной задачи явно избыточно. Чтобы уместится в 16 бит делим множитель 100 и делитель 4096 на 8. Получается ADCA.CH0.RES *12.5 / 512. Чтобы умножить на 12.5 в целых числах - умножаем на 12 и прибавляем еще половинку: (ADCA.CH0.RES * 12us + ADCA.CH0.RES>>1) >> 9
0
0 / 0 / 0
Регистрация: 19.10.2010
Сообщений: 219
04.03.2011, 14:48 5
Спасибо. Теперь все стало понятно.
0
0 / 0 / 0
Регистрация: 15.11.2010
Сообщений: 148
04.03.2011, 17:20 6
Проверил только что, все происходит быстро, но вот результаты далеки от тех, что нужны. К примеру при ADCA.CH0.RES = 2100 я получаю не 50+ как при том варианте, что я использовал изначально, а порядка 27-29.. Похоже где-то 1 бит теряется, хотя при умножении на 12.5 не может ничего потеряться.
0
0 / 0 / 0
Регистрация: 09.02.2011
Сообщений: 544
04.03.2011, 17:43 7
помоему проблема в прямом использовании чтения из ADC.
попробуйте переписать код так :
i=ADCA.CH0.RES;
i=((i * 12us) + (i>>1)) >> 9;

скобки особо рояли не играют - они просто иногда помогают от желания компилятора заоптимизировать что не нужно.
а вот применение переменной - позволит стабильно иметь не измененное значение величины. потому как есть вероятность что при втором чтении значения ADC в нем буде другое значение и формула теряет смысл.
0
0 / 0 / 0
Регистрация: 15.11.2010
Сообщений: 148
04.03.2011, 17:47 8
А вот так все заработало:
Код
unsykned short RESULT =  ((unsykned int)(ADCA.CH0.RES*12)+(unsykned int)(ADCA.CH0.RES>>1))>>9;
Видимо компилятор пытался 8бит операции производить.
По поводу прямого чтения результата ADCA, то тут нет проблем, преобразование единичное
0
0 / 0 / 0
Регистрация: 19.10.2010
Сообщений: 219
04.03.2011, 17:51 9
Все равно правильней читать из АЦП в переменную и с ней потом оперировать. Иначе может вылазить непредсказуемый глюк, который замаетесь отлавливать...
0
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
04.03.2011, 18:21 10
Да, да, правильнее, конечно, вычитать значение из регистра АЦП в переменную, а потом проводить с ней манипуляции.
0
0 / 0 / 0
Регистрация: 27.06.2010
Сообщений: 405
04.03.2011, 18:23 11
Цитата Сообщение от BuTbKo
А вот так все заработало:
Код:
unsykned short RESULT = ((unsykned int)(ADCA.CH0.RES*12)+(unsykned int)(ADCA.CH0.RES>>1))>>9;

Видимо компилятор пытался 8бит операции производить.
По поводу прямого чтения результата ADCA, то тут нет проблем, преобразование единичное

Это потому, что вокруг ADCA.CH0.RES>>1 надо было скобки поставить, у сдвига приоритет ниже, чем у сложения :)
А перобразование к (unsykned int) тут нафиг не нужно.
0
0 / 0 / 0
Регистрация: 15.11.2010
Сообщений: 148
04.03.2011, 19:06 12
действительно, ниже.. Я почему-то думал, что наоборот выше, спасибо
0
04.03.2011, 19:06
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.03.2011, 19:06
Помогаю со студенческими работами здесь

Умножение и деление чисел
Здравствуйте уважаемые форумчане. По ходу выполнения задания возник вопрос. Есть у нас пример...

Умножение и деление чисел
Ребят всем привет , можете подсказать команду умножения и деления для эмулятора i8080?

Деление больших чисел
здравствуйте. есть число X, где каждая цифра представляется в виде одного байта с лева направо...

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

Деление больших чисел
Привет всем. Написал функцию для деления больших чисел, но к сожалению вычисления идут очень долго....

Деление больших чисел
Доброго времени суток граждане математики,подскажите пожалуйста каким образом можно разделить к...

Деление больших чисел
Здравствуйте, уважаемые форумчане. Необходимо разделить большое чило на большое число. Эти числа...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru