Страница 1 из 1

Переполнение при умножении

Добавлено: Ср дек 22, 2021 22:49:10
Roman Solovey
Всем привет. Не могу понять в чем проблема.
Имею следующую строку кода: veight = (adc_send * veight_etal) ;
veight - 64бит
adc_send - 32бит
veight_etal - 32бит константа = 1000
когда adc_send приближается к значению 4509930 то происходит переполнение и в переменной veight я получаю 107 в место 4509930000
почему так происходит? ведь переменная результата 64 бит
а если сделать adc_send - 64бит то все работает как нужно

Re: Переполнение при умножении

Добавлено: Ср дек 22, 2021 23:00:09
COKPOWEHEU
Потому что сначала происходит умножение, и только потом - приведение к нужному типу. Можете объявить свою константу как 1000ULL, например.

Re: Переполнение при умножении

Добавлено: Ср дек 22, 2021 23:03:51
veso74
Попробуйте

uint64_t veight = ((uint64_t)adc_send * veight_etal);

Re: Переполнение при умножении

Добавлено: Ср дек 22, 2021 23:08:55
Roman Solovey
так что получается, что умножение происходит в переменную adc_send ? а потом только в veight ?

Добавлено after 1 minute 25 seconds:
uint64_t veight = ((uint64_t)adc_send * veight_etal);
так легче уже саму переменную сделать 64 бит и все.
или в вашем примере мы потом не будем занимать память?

Re: Переполнение при умножении

Добавлено: Ср дек 22, 2021 23:14:08
veso74
Зависит от компилятора. Должно занимать немного больше памяти только во время выполнения операции.
А некоторые компиляторы достаточно "умны" и это не имеет значения - будет оптимизация и будет такой же объем памяти.

Можно и так:

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

uint32_t adc_send = 4509930;
uint32_t veight_etal = 1000;
...
uint64_t veight = adc_send; 
veight *= veight_etal;

Re: Переполнение при умножении

Добавлено: Ср дек 22, 2021 23:19:22
Roman Solovey
ага, понял. спасибо
но вот еще бы понять почему происходит переполнение? из за того что оно само в себя складывает результат умножения?

Re: Переполнение при умножении

Добавлено: Чт дек 23, 2021 09:12:58
COKPOWEHEU
Я же написал: u32*u32=u32
Но u32*u64=u64, поэтому достаточно привести хоть один аргумент к 64 битам чтобы результат туда влезал.
Аналогично int*int=int, int/int=int, но при этом int*float=float и int/float=float. Именно поэтому 1/2=0, но 1.0/2=0.5

Re: Переполнение при умножении

Добавлено: Чт дек 23, 2021 11:37:09
GoldenAndy
Тип результата выражения определяется максимальным типом операндов. На тип результирующей переменной компилятор не смотрит.
Изображение

Re: Переполнение при умножении

Добавлено: Чт дек 23, 2021 19:19:15
Roman Solovey
спасибо. а подскажите из какой книги этот скрин?

Re: Переполнение при умножении

Добавлено: Чт дек 23, 2021 19:54:57
GoldenAndy
Roman Solovey, ищите в гугле
"Книга по работе с WinAVR и AVR Studio"

Это книга (или цикл статей) автора Романа Абраша. Книга автором не дописана.

ЗЫ. Автор присутствует на форуме :)

Re: Переполнение при умножении

Добавлено: Чт дек 23, 2021 20:33:24
Roman Solovey
спасибо. буду изучать)

Re: Переполнение при умножении

Добавлено: Пт дек 24, 2021 01:41:11
pasha_zv
ага. предсказанное будущее начинается.
расскажу на микрочипе, пусть поржут
===============
...
имхо, те, которые топовые- скоро на "андуриновую" структуру перейдут...
а, фигли, вот вам - "outUSB2.0(byte)"... и не думайте.... там всё уже работает....
но, ножки трогать- низя.....

наверное- это хорошо.... скорость разработки увеличивается... но... с другой- "болты" закручивают- в плане творчества....
.....
К сожалению, по причине ограниченной продолжительности жизни, придётся решать, что приоритетнее.
На ногодрыге ВСЁ сделать нельзя (не хватит времени на решение задачи). Надо отдавать что-то на откуп другим людям - или разработчикам кремния (хардварный USB тот-же), или (далее) авторам компиляторов, или (далее) каким-то осям и бибилиотекам ( и т.д.).
Большинство уже сделало выбор в пользу "сейчас любой ценой". Все стареют ведь. А надо успеть.
Жду не дождусь, когда ардуинские "скетчи" начнут применять в ответственных приложениях.
Закупился попкорном в ожидании какого-нибудь мирового коллапса, устроенного программистами (типа, перестали работать все банковские карточки мира на три дня или что-то в этом духе).Только после глабального 3.14здеца может поменяться вектор коллективного восприятия действительности (и то - не факт, к сожалению)