It's a binary (not decimal) limitation of REALs, as @rdrast points out.
Another way of saying this is that it is a round-off error, where the value you are adding rounds off to 0
Note that, whatever is done, there are, and always have been, roundoff errors in this calculation, even when the value festoonPosition is changing every time, and that roundoff error accumulates over time; this particular case, where the roundoff rounds the delta to 0, is just a special case that happens to be noticed because it is apparent to the naked eye.
TL;DR
... you might get slightly better results with 'festoonPosition + (verticalSpeed * masterTimer.PRE)/60000
That will not help, the problem is the difference in magnitude between [(verticalSpeed/60000) * masterTimer.PRE] (or [(verticalSpeed * masterTimer.PRE)/60000] festoonPosition.
- festoonPosition ~ 50
- delta = (verticalSpeed/60000) * masterTimer.PRE ~ .0115/6000 ~ 2e-6
- Ratio of [festoonPosition:delta] ~ 5e1/2e-6 ~ 2.5e7
REALs are IEEE-754 single-precision floating point with 32 bits (see link by @rdrast): 1 bit for sign; 8 bits for exponent; 24 bits for mantissa. That mantissa is a 24-bit integer, so it has a value between 1 and 2
24 - 1 = 16,777,215 ~ 1.7E7. So that ratio of [festoonPosition:delta] of 2.5e7 means the quantity 2e-6 you are trying to add to festoonPosition~50 is out beyond the 24th least significant bit of the mantissa of festoonPosition.
E.g. if you had a calculator with two displayed places, and you tried to add 0.01 to 1.2, the result should be 1.21, but the displayed number would be 1.2.
I don't know if it would work but if you could convert the CPT calculations to LREAL, that will hopefully kick the can farther enough down the road.
One way to fix this would be to increase the masterTimer.PRE value, but that only kicks the can down the road so far e.g. if you doubled masterTimer.PRE to 20, then you would have the same problem either when festoonPosition increased to ~100 or verticalSpeed decreased to ~0.006.
Another way to fix, or at least ameliorate, this would be to calculate, and accumulate, how much of the delta does not get added each time, and include that accumulation into the sum the next time. This approach would have its own roundoff error, but it should be orders of magnitude less than what you are seeing now.
Ultimately, you are going to have to decide what the smallest movement ((calSpeed-lineSpeed) * (20/34) * masterTimer.PRE / 60000) you want to affect festoonPosition, and assume anything below that is 0.