The core R engine has a serious flaw with the way it expresses output from the Modulus operation:
ceiling((1.99 %% 1) * 100)
Returns: 99 (correct)
ceiling((2.99 %% 1) * 100)
Returns: 100 (incorrect)
The behavior will manifest in any integer value N + 2.99 (e.g. 3.99, etc.). If this is tied to a floating point representation, the system is not expressing the full details of the difference. This is especially disturbing because:
Both (1.99 %% 1)
and (2.99 %% 1)
appear to return 0.99.
Both ((1.99 %% 1) * 100)
and ((2.99 %% 1) * 100)
appear to return 99.
However, if you do any rounding or similar mathematical operations, the invisible residual value for 2.99 flips things in an unexpected way.
While solving this problem for my current application is trivial:
floor((2.99 - floor(2.99)) * 100)
Returns: 99 (correct)
sprintf("%.22f", floor((2.99 - floor(2.99)) * 100))
Returns: 99.0000000000000000000000 (correct)
... I wonder how many other instances that Modulus returns bad values without the underlying detail to show the floating point delta. Is there a way to expose the underlying residual value which Modulus seems to attach? It's otherwise invisible.
EDIT: As per the generous example from andrew.punnett below, print(1.99, digits = 22)
returns 1.99 (no float expansion), while print(1.99 %% 1, digits = 22)
returns 0.98999999999999999. As per the astute eye of Aaron, this appears to be version and / or system dependent.
Thanks!