Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.93/46: Рейтинг темы: голосов - 46, средняя оценка - 4.93
pmdr_soft
0 / 0 / 0
Регистрация: 15.03.2010
Сообщений: 287
1

помогите осилить выражение

01.12.2012, 21:16. Просмотров 8395. Ответов 25
Метки нет (Все метки)

Код
static   uint16_t   persent_to_pwm_9bit(uint8_t persent)
{
return (0x1FF * persent) / 100;
}
persent = 0..100

результат записываю в OCR1.

Считает не правильно. Понимаю, что заморочка с типами. Как победить не знаю.
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.12.2012, 21:16
Ответы с готовыми решениями:

Не могу осилить Makefile, подскжаите пожалуйста.
Здравствуйте господа AVRщики) Захотел прикрутить к меге16 загрузчик USB - BoottoodHID. ...

Помогите упростить выражение!
Не знаю, почему оно вызвало у меня ступор, но я не знаю, что тут можно предпринять:...

Помогите составить выражение
Имеется строки 720 pixel3, 640 pixel нужно убрать всё начиная со слова pixel

Регулярное выражение..помогите написать
Программа делает подсветку исходного кода... хочу написать регулярку для посветки строковых...

Помогите постоить простое выражение
Есть поле: "Номер", может содержать три значения: "1", "2", "3". Требуется в зависимости от...

25
dsodir
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,284
01.12.2012, 21:19 2
(0x1FF * (uint16_t)persent) / 100;
0
dymo2611
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 1,110
01.12.2012, 21:21 3
чтобы не округляло, сразу заложиться на большое число

Код
static   uint16_t   persent_to_pwm_9bit(uint8_t persent)
{
uint32_t dummy; // 32 бита с запасом

dummy = 0x1FF;
dummy *= percent;
dummy /= 100;
return (uint16_t) dummy;
}
0
pmdr_soft
0 / 0 / 0
Регистрация: 15.03.2010
Сообщений: 287
01.12.2012, 21:23 4
кто объяснит логику ? я реально это не понимаю.
0
01.12.2012, 21:23
omt
0 / 0 / 0
Регистрация: 02.11.2004
Сообщений: 1,112
01.12.2012, 21:23 5
мож это код под тиньку ) а вы 32бит- переменные создаёте
0
pmdr_soft
0 / 0 / 0
Регистрация: 15.03.2010
Сообщений: 287
01.12.2012, 21:25 6
Цитата Сообщение от Omt
мож это код под тиньку ) а вы 32бит- переменные создаёте
atmego32
0
pmdr_soft
0 / 0 / 0
Регистрация: 15.03.2010
Сообщений: 287
01.12.2012, 21:26 7
Цитата Сообщение от dsodir
(0x1FF * (uint16_t)persent) / 100;
работает.спасибо. :))

Может поделитесь нигией ?
0
dymo2611
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 1,110
01.12.2012, 21:27 8
Цитата Сообщение от pmdr_soft
кто объяснит логику ? я реально это не понимаю.
если компилятору дать перемножить 2 байта, то он (в большинстве случаев) не будет додумывать, что результат уместится опять же в 2 байта. От просто тупо присвоить 16-тибитное значение 1-байтовой переменной и тем самым обрубит самое интересное.

если же сделать cast на более длинный хранитель, то он такую длину и учтет.
Это старые грабли. Очень старые.
0
Ymk
0 / 0 / 0
Регистрация: 18.03.2010
Сообщений: 2,233
01.12.2012, 21:46 9
Цитата Сообщение от dymo2611
если компилятору дать перемножить 2 байта, то он (в большинстве случаев) не будет додумывать, что результат уместится опять же в 2 байта.
имхо, компилятор должен был сам второй операнд расширить до 2х (как минимум) байт, ибо первый операнд больше одного байта.
0
dymo2611
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 1,110
01.12.2012, 22:01 10
Цитата Сообщение от Ymk
Цитата Сообщение от dymo2611
если компилятору дать перемножить 2 байта, то он (в большинстве случаев) не будет додумывать, что результат уместится опять же в 2 байта.
имхо, компилятор должен был сам второй операнд расширить до 2х (как минимум) байт, ибо первый операнд больше одного байта.Короче, это пример того, как компилятор не видит очевидных вещей: даны 2 байта на переумножение с 1 байтом => результат 2 байта.

Кастом uint16_t компилятор получил пару по 2 байта на переумножение. По уму надо заложится на результат из 4 байт. Но и тут он стопудово урезал до 16 бит. Благо прокатило.
0
ysp
0 / 0 / 0
Регистрация: 19.10.2012
Сообщений: 44
03.12.2012, 17:25 11
Сказать просто так, что с байтами будет, трудно. AVR Studyo байты умножать не умеет, только инты.
Например:
Код
int main() {
char ci=50, cj=52, ck;
ck=ci*cj/26;
}
результат правильный (100) будет, хотя 50*52=2510 за байтовую сетку далеко выходит.
А вот с интами нет. Промежуточный выход и всё, кык. Как заставить компил работать с лонгами. Описать (или преобразовать) первый исполнимый операнд как лонг. А дальше все операции пойдут как лонг. Не забывать про скобки!
Например:
Код
int main() {
int i=10000, j=8192, k;
k=i*j/4096;  // результат неправильный
k=(long)i*j/4096;  // правильный
long i1=1; k=i1*i*j/4096; // смешной, но правильный
k=i1*(i*j/4096); // и смешной, и неправильный
}
0
Ymk
0 / 0 / 0
Регистрация: 18.03.2010
Сообщений: 2,233
03.12.2012, 20:30 12
ysp, вы косяк из первого поста объясните;)
0
dymo2611
0 / 0 / 0
Регистрация: 10.03.2012
Сообщений: 1,110
03.12.2012, 20:34 13
Цитата Сообщение от Ymk
ysp, вы косяк из первого поста объясните;)
Объяснили же, что от (0x1FF * persent) остаётся LSB.
0
Ymk
0 / 0 / 0
Регистрация: 18.03.2010
Сообщений: 2,233
03.12.2012, 21:04 14
dymo2611, из вашего объяснения я понял, что компилятор - дурак. я согласен с этим. но тут пришел капитан ysp и рассказал чо почем, но только не про случай из первого поста.
0
ysp
0 / 0 / 0
Регистрация: 19.10.2012
Сообщений: 44
03.12.2012, 21:07 15
Ymk. Только тем, что я на AVR Studyo 4.19 проги тестил. А у ТС другой компилятор.
0
omx
0 / 0 / 0
Регистрация: 11.11.2016
03.12.2012, 21:21 16
Косяк в первом посте может быть если размер типа int у компилятора равен ширине шины МК, а МК у ТС - 8-битный. Тогда и только тогда константа может иметь размер 8 бит. Так как константы без явного указания тоипа всегжа имеют тип sykned int. К такому поведению можно принудить компилятор опцией, например для avr-gcc -mint8, такой же функционал видел для пиковских компиляторов. Для 16/32-битников такого быть не может.

ysp, это не студия перемножать байты не умеет, а в стандарте языка Си английским по белому описано поведение известное как integral promotion. Это означает что любой байт участвующий в выражении будет расширен до слова (2х байт), обоработан, а уж как рузультат будет интерпретирован - дело десятое.
0
ysp
0 / 0 / 0
Регистрация: 19.10.2012
Сообщений: 44
04.12.2012, 09:47 17
omx, я же не пишу, самостийно Студия байты не умножает или стандарт ей не позволяет.
А вот интересный пример строго по ТС:
Код
int main() {
unsykned char cu=90, c100=100;
unsykned int iu, i100=100;
iu=0x1FF*cu;
iu/=100;                  // работает 459
iu=0x1FF*cu/i100;  // работает 459
iu=0x1FF*cu/100;  // не работает и не 0, а 65341
iu=0x1FF*cu/c100; // не работает и не 0, а 65341
}
уважаемый omx, ваше мнение, почему так?
0
kytikot
0 / 0 / 1
Регистрация: 27.01.2010
Сообщений: 3,435
04.12.2012, 10:33 18
Почитайте в любом учебнике по Си главу про явное и неявное преобразование типов, и использование этих преобразований в выражениях.
0
ysp
0 / 0 / 0
Регистрация: 19.10.2012
Сообщений: 44
04.12.2012, 11:25 19
Цитата Сообщение от kytikot
Почитайте в любом учебнике по Си главу про явное и неявное преобразование типов, и использование этих преобразований в выражениях.
Прочитал лет 25 тому назад.
Вы по делу можете ответить?
По строкам конкретно?
Нет? Тогда зачем словестностью форум засорять?
Прочитайте пример. Посмотрите где и как преобразуются типы. А нам ответьте, почему так.
Почему при явном описании переменной происходит одно, а при скрытом, по стандату д.б. так, а в действительности - нет. Не знаете стандарта? Тогда чего нас призываете его изучать?
Итак, программа:
Код
int main() {
const int k=0x16C;
char c=90, c100=100;
int i;
int i100=100;
i=k*c; i/=100;
i=k*c/i100;
i=k*c/100;
i=k*c/c100;
}
работает, вне зависимости знаковые переменные или нет.
Соит k=0x16D сделать, так результаты в разнобой пойдут.
Потому, что промежуточный результат за знаковую положительную границу перейдёт и будет интерпретироваться по разному.
Эх, знатоки учебников. Программы писать надо, а не никотин книжный потреблять. Не в меру, вреден он!
0
kytikot
0 / 0 / 1
Регистрация: 27.01.2010
Сообщений: 3,435
04.12.2012, 15:58 20
Если конкретный компилятор работает не так, как в стандарте - это проблемы не стандарта, а конкретно этого компилятора, и конкретного программиста, который работает с этим компилятором.
В конце-концов, ничего идеального нет, и нужно некоторые вещи принимать такими, какие они есть. Запомни этот момент, как это работает (или не работает), и применяй это на практике. Иногда это экономически и морально выгодней, чем тратить время и нервы на выяснение причин.

P.S. Я не буду поддерживать дискуссию по этому вопросу.
0
04.12.2012, 15:58
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.12.2012, 15:58

Помогите написать регулярное выражение
Есть вот такая строка : Исполнитель:</td><td><a href="/abc/artist/3608/">Макаревич</a></td> ...

Помогите составить регулярное выражение?
Kakim dolzhen bit' regular exprasion ? Mne nuzhno zasunut' ve Array vse zifru iz string var...

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.