Найти в Дзене
informatics_for_everyone

Программирование. Arduino. Целочисленное и вещественное деление

Оглавление

При целочисленном делении результат не округляется по "математическим" правилам, дробная часть просто отсекается, фактически это округление вниз: и 9/10 и 1/10 дадут 0.
При использовании
float само собой получится 0.9 и 0.1.
Если нужно целочисленное деление с округлением вверх, его можно реализовать так: вместо
x / y записать (x + y - 1) / y.
Рассмотренные выше примеры деления на 10 дадут результат 1.

Для округления по обычным математическим правилам можно использовать функцию
round(), но она довольно тяжёлая, так работает с float.

Переполнение переменной

При переполнении в бОльшую сторону из нового значения вычитается максимальное значение переменной, и у неё остаётся только остаток.
Пример:
// тип данных byte (0.. 255)
byte val = 255;
// тут val станет равным 0
val++;
// а тут из нуля станет 246
val -= 10;
// переполним! Останется 13
val = 525;
// и обратно: val равна 236
val = -20;


Особенности float

Если в выражении нет float чисел, то вычисления будут иметь целый результат (дробная часть отсекается). Для получения правильного результата нужно писать преобразование (float) перед действием, использовать float числа или float переменные. Также есть модификатор f, который можно применять только к цифрам float. Смысла в нём нет, но такую запись можно встретить.


Пример:
float val; // далее будем присваивать 100/3, ожидаем результат 33.3333
val = 100 / 3;
// посчитает НЕПРАВИЛЬНО (результат 33.0)
int val1 = 100;
// целочисленная переменная
val = val1 / 3;
// посчитает НЕПРАВИЛЬНО (результат 33.0)
float val2 = 100;
// float переменная
val = val2 / 3;
// посчитает правильно (есть переменная float)
val = (float)100 / 3;
// посчитает правильно (указываем (float) )
val = 100.0 / 3;
// посчитает правильно (есть число float)
val = 100 / 3.0f;
// посчитает правильно (есть число float и модификатор)

При присваивании
float числа целочисленному типу данных дробная часть отсекается. Если хотите математическое округление – его нужно использовать отдельно.

Пример:
int val;
val = 3.25;
// val станет 3
val = 3.92;
// val станет 3
val = round(3.25);
// val станет 3
val = round(3.92);
// val станет 4

Следующий важный момент: из за особенности самой модели "чисел с плавающей точкой" – вычисления иногда производятся с небольшой погрешностью. Смотрите (значения выведены через порт):
float val2 = 1.1 - 1.0;
// результат 0.100000023 !!!
float val4 = 1.5 - 1.0;
// результат 0.500000000