C/C++

Как работает математика в C++ Почему (32-6)/100*20 = 0

Привет.
Пишу программу для Arduino, там синтаксис C++
У меня есть переменная M, которая должна получить целочисленное число (int).
Я пишу условие M = round( (32-6) / 100 * 20 ); И компилятор выдаёт 0.
Видимо числа надо привести к формат float и тогда посчитается правильно, но нет =(
M = round( (32-6) / float(100) * float(20) );

Сам код вот такой:
void GrafPosMol(int a){
M = round( (32-6) / 100 * a );
Serial.println(M);
}
int M;
M = (int)round((32. - 6.) / 100. * 20.);
printf("%i\n", M);

void GrafPosMol(int a){
Serial.println((int)round(0.26 * a));
}
Владимир Ольховский
Владимир Ольховский
77 803
Лучший ответ
Имеется выражение: (32-6) / 100 * 20
Сначала выполняются действия в скобках, получается 26 / 100 * 20
Затем действия выполняются по порядку. Для начала - целочисленное деление 26 / 100. Получается 0 * 20. А при умножении 0 на любое число получается 0, если ты вдруг забыл школьную математику, юный падаван. И при округлении 0 тоже получится 0. Такие дела.
Александр Черноскутов Я не знал что в С++ всё так сложно =))
всё просто - (32-6) / 100 - это целочисленные операции.
/ 100.0 - уже с плав. точкой. И не привели к целому перед выводом.

По той-же самой причине 1/2 = 0; но 1.0/2.0 = 0.5
Пример:
https://www.ideone.com/6Hvzi6

Таков путь. =)
aidar_1803.kz
aidar_1803.kz
84 764
RE:   Кажись Arduino не умеет в 2 действия, только одно

А вот и умеет! Просто в C++ есть такая вещь, как ПЕРЕГРУЗКА операций. И получается, что операция деления обозначается одинаково и для целых типов, и для вещественных. Но в действительности это две разные операции, а компилятор выбирает конкретную из них только по тому факту, какой тип у фактических аргументов.

Выходит, что если оба фактических аргумента выглядят как целые числа, то выбор соответствия операции деления никогда не дойдёт до вещественного деления, ведь проще подставить операцию деления целых чисел!!! А чтобы компилятор выбрал именно вещественное деление, требуется хотя бы один фактический аргумент привести к виду вещественного числа. Либо применить явное приведение типа к одному из них (хотя это нерационально по отношению к константе).

Остальное уже объяснили.
Olzhas__ Serikbaiuly__
Olzhas__ Serikbaiuly__
16 172
Olzhas__ Serikbaiuly__ Не следует забывать, что в C++ уникальным идентификатором любой операции является вовсе не знак операции, а (!!!) комбинация из знака операции и типов всех формальных параметров, именно так! Это означает, что могут существовать операции совпадающие по своему знаку, но выполняющиеся по разному. Такая множественность операций с одинаковым знаком называется ПЕРЕГРУЗКОЙ, а операции — перегруженными.

Типичный пример — операции сдвига. Если первый фактический аргумент имеет целочисленный тип, то над ним выполняется поразрядный сдвиг. Но если первый аргумент имеет потоковый тип (stream), то выполняется операция потокового ввода/вывода.
Olzhas__ Serikbaiuly__ Кстати, перегрузка не ограничивается операциями, она применима и к функциям. Вполне допустимо объявлять функции-тёзки, если перечень типов формальных параметров имеет хотя бы единственное различие (ну или больше, чем одно).
а без round
Александр Дьяченко В фортране и без раунда будет ноль :)
Александр Черноскутов Но если оставить только 32-6 то норм. Или если 100 / 3 тоже норм
Александр Черноскутов В других языках тоже всё нормально: Delphi, PHP, JS
Александр Черноскутов Проблема именно в том, что происходит 3 действия. Если происходит 2 действия то всё нормально считается. Что за дич =)