Not sure why, but if I add big to small fp numbers it seems that the increment error is bigger:
#include <iostream>
#include <math.h>
int main() {
std::cout.precision(50);
const int numLoops = 1000;
const long length = 10000;
const double rate = 0.1;
long totalLength = length * numLoops;
long long steps = (long long)(totalLength / rate);
double sum = 0.0;
double sumRemainder = 0.0;
for (long long step = 0; step < steps; step++) {
if (sumRemainder >= length) {
sumRemainder = fmod(sumRemainder, length);
}
sum += rate;
sumRemainder += rate;
}
std::cout << " length: " << length << std::endl;
std::cout << " num loops: " << numLoops << std::endl;
std::cout << " rate: " << rate << std::endl;
std::cout << " steps: " << steps << std::endl << std::endl;
std::cout << " sum: " << sum << std::endl;
std::cout << " sum remainder: " << sumRemainder << std::endl;
std::cout << " error: " << abs(totalLength - sum) << std::endl;
std::cout << " error remainder: " << abs(length - sumRemainder) << std::endl;
std::cout << std::endl;
}
The only differences between the two sums are that one is for all steps, while on the other I simply fmod the result once reach a limit (thus, it clamp to a small value):
sumRemainder = fmod(sumRemainder, length);
It seems that's the cause it introduce low error while summing the same amount: 1.884836819954216480255126953125e-05
vs 0.01887054927647113800048828125
Can someone please explain to me why this happens with a clever example?