реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Арифметические операции в WinAVR
koluna
сообщение Sep 22 2009, 09:20
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061



Здравствуйте!

Объясните, пожалуйста, принцип работы компилятора на следующих тест-примерах.

Пример 1 (вычисления правильные):
Код
unsigned char Tmpr = 235 -  (unsigned long) 400 * 7800 / 14200; // = 16


Пример 2 (вычисления неправильные):
Код
unsigned char Tmpr = 235 -  400 * 7800 / 14200; // = 236


Почему требуется обязательное приведение типа одного из операндов к unsigned long, а не результата вычисления?
И почему оно вообще требуется?

Благодарю заранее!

Сообщение отредактировал n_bogoyavlensky - Sep 22 2009, 09:25


--------------------
Благодарю заранее!
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Sep 22 2009, 09:37
Сообщение #2


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



400 * 7800 = 3120000
Как по-вашему, укладываемся в char?

И вообще, нафига какие-то приведения, когда сплошные константы?
unsigned char Tmpr = 235 - 400UL * 7800 / 14200; // = 16

Вменяемый компилятор должен подставить результат на уровне препроцессорной обработки


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 22 2009, 10:09
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(n_bogoyavlensky @ Sep 22 2009, 12:20) *
Почему требуется обязательное приведение типа одного из операндов к unsigned long, а не результата вычисления?
Потому что существуют правила языка. Компилятор выбирает конкретную функцию вычисления исходя из разрядности операндов. Вы же хотите, чтобы в коде
Код
uint8_t a =2; b = 3; uint32_t c = a * b;
компилятор использовал 32-битное умножение?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
koluna
сообщение Sep 22 2009, 11:51
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1 040
Регистрация: 3-01-07
Пользователь №: 24 061



Цитата(MrYuran @ Sep 22 2009, 12:37) *
400 * 7800 = 3120000
Как по-вашему, укладываемся в char?


Почему в char?
Как минимум в unsigned int.

Цитата
И вообще, нафига какие-то приведения, когда сплошные константы?
unsigned char Tmpr = 235 - 400UL * 7800 / 14200; // = 16


Ну написал же: "... тестовый пример...". В реальности там переменные стоят...

Цитата
Вменяемый компилятор должен подставить результат на уровне препроцессорной обработки


Ясное дело, что с константами операции выполнятся на этапе препроцессорной обработки...
Речь не об этом...

Цитата(Сергей Борщ @ Sep 22 2009, 13:09) *
Потому что существуют правила языка. Компилятор выбирает конкретную функцию вычисления исходя из разрядности операндов. Вы же хотите, чтобы в коде
Код
uint8_t a =2; b = 3; uint32_t c = a * b;
компилятор использовал 32-битное умножение?


По поводу правил уже догадался, поэкспериментировав smile.gif
Т. е., как минимум один из операндов должен иметь тип unsigned long...


--------------------
Благодарю заранее!
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 22:22
Рейтинг@Mail.ru


Страница сгенерированна за 0.01369 секунд с 7
ELECTRONIX ©2004-2016