работа с числами float
- Войдите на сайт для отправки комментариев
Здравствуйте! У меня возникла некоторая проблема с правильностью вычислений. Прилагаю код, на переменные не смотрите.
#define delitel_T1_1 244.140625 uint16_t cnt_rpm; float r, f, f1, f2; void setup() { Serial.begin(9600); r = 0.1; f = 0.0; f1 = r * 200.0; // 200; f2 = delitel_T1_1 / f2; // 1,22; while (f2 > 1.0) {r = r + 0.1; f2 = r * 200.0; f2 = delitel_T1_1 / f2; Serial.println(" r = " + String(r) + "; "); } //r = 1.3; // ЗДЕСЬ r РАВНО 1.30 Serial.println("r = " + String(r) + " после расчётов"); // ЗДЕСЬ f РАВНО 18.00 ВСЁ ПРАВИЛЬНО f = ((3.0 - r + 0.1) * 10.0); Serial.println("f = " + String(f) + "; "); // f = 18.00 // ПОЧЕМУ ЗДЕСЬ CNT_RPM = 17 .... ??? НЕПРАВИЛЬНО!!!!!!! cnt_rpm = int(f); Serial.println("cnt_rpm = " + String(cnt_rpm) + "; "); // 17 // ПОЧЕМУ ЗДЕСЬ ТОЖЕ CNT_RPM = 17 .... ??? НЕПРАВИЛЬНО!!!!!!! cnt_rpm = int((3.0 - r + 0.1) * 10.0); Serial.println("cnt_rpm = " + String(cnt_rpm) + "; "); } void loop() { }
Вся загвоздка для меня после цикла
while (f2 > 1.0) {r = r + 0.1; f2 = r * 200.0; f2 = delitel_T1_1 / f2; Serial.println(" r = " + String(r) + "; "); }
В цикле переменная r увеличивается с шагом 0,1 , происходит проверка переменной f2 на больше, чем 1. Итог - как только f2 стало меньше 1.0, переменная r (как должно быть для меня) принимает значение 1.30! Далее нужно вычислить переменную cnt_rpm, которая должна быть 18, но она у меня принимает значение 17.... CNT_RPM вычисляю 2-мя способами (строки 27 - 33).
Самое главное, почему, когда я раскомментирую строку 19 (чем дублирую значение переменной r после цикла)
//r = 1.3;
, тогда CNT_RPM принимает правильное значение (18) ...
Кто может подсказать в чем подвох.
Просто погрешность накопилась. Вот с чего Вы взяли, что здесь неправильно?
напечатайте в первой строке не с двумя знаками, а с 6 или 8 и увидите, что там она равна не 18, а, скажем 17,999999. Ну, а при преобразовании к int, таком, как в строке №4, дробная часть просто отбрасывается - вот и получается 17. Всё нормально.
У Вас в коде в строках №№13-18 крайне неудачно вычисляется r (Вы её итеративно вычисляете, чего следует всячески избегать) вот и накопилась ошибка. Вот здесь есть сравнение итеративного вычисления (такого, как у Вас) и более правильного - посмотрите, сравните накопленные ошибки.
С флоатом вообще нужно аккуратно работать и понимать как он устроен, а то, при неаккуратной работе, можно и при вычитании чисел, отличающихся на 1, получить результат больше сотни (см., например).
Да, СПАСИБО, разъяснили на пальцах! Ведь читал же у AlexaGiver'a про осторожность с float'ом. Но вот когда дело до практики, тогда и учимся все мы на ошибках! Евгений, спасибо за предоставленные статьи, очень полезно!
Ведь читал же у AlexaGiver'a ...
Тогда не удивительно :-)
Ведь читал же у AlexaGiver'a ...
Тогда не удивительно :-)
Гувер прям дышит в затылок Петровичу...
Ведь читал же у AlexaGiver'a ...
Тогда не удивительно :-)
Лана, лана, у него тоже полезные весчи встречаются (мошт спертые), но узнал от него. Вот на днях, усб тестер заказал себе, для контроля аккумуляторов литиевых. Вроде оно и на поверхности, а тож.((((
привлекательность Гайвера основана на "щас по-быстрому соберём девайс из гавна и палок и без всяких знаний".
и на это снят видосик и оно работает. безпроигрышный ход. ну и нельзя сказать что бездельник - времени и сил на всю эту деятельность он тратит до фига.
кроме того он юн и это ещё больше привлекает к нему таких же "сваять быстренько потому что очень нужно"
Вопросик! Есть такой код
У меня много где есть MIN_SPEED, и я его хочу вставлять где мне нужно, как мне правильно делать вычисление в 4 строке? Не уследить просто за числом 0.1
0,1 это не 0.1
Ну, про ошибку в константе Вам уже сказали.
Еще раз помогли мне исправить ошибку, спасибо!