Как разбить двухбайтную переменную на 2 байта в СИ?

Обсуждаем контроллеры компании Atmel.
Reflector
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Re: Как разбить двухбайтную переменную на 2 байта в СИ?

Сообщение Reflector »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=4137391#p4137391"]тогда компилятор для промежуточных вычислений зарезервирует 16 бит переменную (2 регистра)[/uquote]
Он это и так сделает.
Писал бы TC на С++ в более-менее нормальной IDE, тогда мог бы сделать так и посмотреть какой у суммы тип:

Изображение
Реклама
Dimon456
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Re: Как разбить двухбайтную переменную на 2 байта в СИ?

Сообщение Dimon456 »

GoldenAndy писал(а):Ардуина - это плюсы, соответственно, все прелести ООП доступны.
Какой компилятор используется? avr-g++?
Это стандартный компилятор, который входит в набор WinAVR-20100110, и это не чистый c++.
Реклама
Аватара пользователя
GoldenAndy
Поставщик валерьянки для Кота
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA
Контактная информация:

Re: Как разбить двухбайтную переменную на 2 байта в СИ?

Сообщение GoldenAndy »

Ivanoff-iv писал(а):тут лучше написать так:
Код:
sum = (uint16_t) (var[0] + var[1] + var[2]) / 3;
Я таки дико извиняюсь, но тут просто повезло, что по умолчанию компилятор приводит вычисления к int (avr gcc приводит к знаковому int).

Ибо вы приводите к uint16_t результат сложения.
Т.е. сначала выполнится сложение в скобках, а потом приведение результата.
Разрядность результата операции - это максимальная разрядность операндов.
У операции (var[0] + var[1] + var[2]) все операнды 8-битные.

Правильно вот так:

Код: Выделить всё

sum = ( (uint16_t)var[0] + var[1] + var[2]) / 3;
Тогда для выражения в скобках результат будет принят как uint16_t и не потеряются значения на переполнении.
Результат скобок будет uint16_t, деление на 3 тоже пройдет в 16-битной математике.
СпойлерИзображение
© ARV
Dimon456, я не знаю, какой компилятор пользует абдурина. Не пользовался.
У меня есть одна или две наны на меге 328, исключительно как удобный формфактор для втыкания в макетку.
А для написания кода - АВР студия.
Вложения
arv1.jpg
(159.17 КБ) 433 скачивания
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Kalisnik
Мучитель микросхем
Сообщения: 430
Зарегистрирован: Вс апр 18, 2021 15:43:55

Re: Как разбить двухбайтную переменную на 2 байта в СИ?

Сообщение Kalisnik »

GoldenAndy писал(а):Правильно вот так:
Код:
sum = ( (uint16_t)var[0] + var[1] + var[2]) / 3;
Спасибо! Были такие подозрения. :)

Добавлено after 3 minutes 4 seconds:
Учусь в CVAVR. Ардуино не использую, так как не вижу ни каких перспектив кроме домашних поделок.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Как разбить двухбайтную переменную на 2 байта в СИ?

Сообщение Ivanoff-iv »

GoldenAndy писал(а):Я таки дико извиняюсь,
да, точно, поторопился... :oops:
но! кодевижен не всегда приводит к инту - его поведение зависит от наличия галочки Project->configure->C Compiler->Promote char to int
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Реклама
Kalisnik
Мучитель микросхем
Сообщения: 430
Зарегистрирован: Вс апр 18, 2021 15:43:55

Re: Как разбить двухбайтную переменную на 2 байта в СИ?

Сообщение Kalisnik »

Ivanoff-iv, полезная информация. Спасибо! :)
Реклама
Аватара пользователя
GoldenAndy
Поставщик валерьянки для Кота
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA
Контактная информация:

Re: Как разбить двухбайтную переменную на 2 байта в СИ?

Сообщение GoldenAndy »

Ivanoff-iv, ситуация в том, что никогда нельзя доверять дефолтовым настройкам и умолчаниям. К примеру, знаковость char...
правильней помнить о приведении типов и учитывать выходы за диапазоны, что бы не выстрелить себе в ногу.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Ответить

Вернуться в «AVR»