Я недавно создал эту простую программу, чтобы найти среднюю скорость.
Средняя скорость = Δx / Δt
Я выбрал х как функцию т как х = t^2
Следовательно v = 2t
также, avg v = (x2 - x1) / (t2 - t1)
Я выбрал интервал, чтобы быть т = 1s to 4s
. Подразумевает х идет от 1 to 16
Следовательно avg v = (16 - 1) / (4 - 1)
= 5
Теперь программа:
#include <iostream>
using namespace std;
int main() {
float t = 1, v = 0, sum = 0, n = 0; // t = time, v = velocity, sum = Sigma v, n = Sigma 1
float avgv = 0;
while( t <= 4 ) {
v = 2*t;
sum += v;
t += 0.0001;
n++;
}
avgv = sum/n;
cout << "\n----> " << avgv << " <----\n";
return 0;
}
Я использовал очень маленькие приращения время рассчитать скорость во многих моментах. Теперь, если приращение T составляет 0,001, среднее значение V рассчитывается как 4,99999.
Теперь, если я положу приращение T как 0,0001, Avg V становится 5,00007!
Дальнейшее уменьшение шага до 0,00001 приводит к avg v = 5,00001
Почему это так?
Спасибо.
В базе 2
0.0001
а также 0.001
являются периодическими числами, поэтому они не имеют точного представления. Один из них округляется в большую сторону, а другой округляется в меньшую сторону, поэтому, когда вы их суммируете, вы получаете разные значения.
Это то же самое, что происходит в десятичном представлении, если вы выбираете числа для суммирования соответственно (предположим, что каждая переменная может содержать 3 десятичных знака).
Для сравнения:
a = 1 / 3; // a becomes 0.333
b = a * 6; // b becomes 1.998
с:
a = 2 / 3; // a becomes 0.667
b = a * 3; // b becomes 2.001
оба должны (теоретически) привести к 2
но из-за ошибки округления они дают разные результаты
В десятичной системе, так как 10
делится на простые числа 2
а также 5
только дроби, знаменатель которых делится только на 2
а также 5
могут быть представлены конечным числом десятичных цифр (все остальные дроби являются периодическими), в базисе 2 могут быть точно представлены только дроби, имеющие в качестве знаменателя степень 2. Попробуйте использовать 1.0/512.0
а также 1.0/1024.0
как шаги в вашей петле. Кроме того, будьте осторожны, потому что если вы выберете слишком маленький шаг, у вас может не хватить цифр, чтобы обозначить его в float
тип данных (т.е. использовать double
s)