In general a float has six decimal digits of precision.
That error propagates and accumulates with each operation. That is partially why it is important to keep a single canonical source of numbers and numbers based on get get recomputed.
Exactly how it accumulates and propagates depends entirely on your program, your algorithms, even your compiler options.
A simple example of error accumulation and propagation: float sum = 0; for(i=0; i<10000; i++) sum += 0.0001; The end result is theoretically 1.0 if you were doing paper math, but with finite numbers in floating point the result is not quite what you expect. Even though each individual number has six decimal digits of precision, by the time you have summed the result 10000 times the error accumulates to something significant.
So really it is important to detail HOW you are using the floating point numbers. If your code allows error to accumulate and propagate issues like you described can occur. If your code limits error accumulation and propagation you can get expected results on all platforms and devices.