When using modulo with certain values, the result appears to be incorrect. I haven't worked out what the pattern is for values that cause this behaviour, and the bug only appears to exist on iOS. Reanimated, Android and Web appear to behave correctly.
As an example, the operation 9999999999 % 10 === 9 in JS. In Reanimated modulo(new Value(9999999999), 10) === 9 on web and Android. However on Reanimated iOS I get a result of 0.
Initially I thought this might have been an issue with being above max 32bit int, but that doesn't appear to be the case as some numbers give the correct result, while some values much smaller than max int do not.
Reanimated Web | Reanimated Android | Reanimated iOS
---|---|---
9 | 9 | 0
|
| 
This GIF shows some of the unusual results that are given from my expo snack. Values appear to be mostly incorrect when the start value is 9999999999 (or a similarly large number) but setting the value to 1234567 and then gradually increasing the value, the result appears to be correct, even when exceeding a value of 9999999999.
The left-hand side is pure JS (value % 10) while the right side is the result from reanimated (modulo(animatedValue, 10)).

https://snack.expo.io/@levibuzolic/reanimated-math
import * as React from 'react';
import Animated from 'react-native-reanimated';
import { ReText } from 'react-native-redash';
const { concat, Value, modulo } = Animated;
const { useRef } = React;
export default function App() {
const { current: animValue } = useRef(new Value(9999999999));
return <ReText text={concat('', modulo(animValue, 10))} />;
}
For the sample app I've tested in Expo 37.0.0 (which I believe uses Reanimated 1.70)
The issue also exists in my current production app running:
Looking into this further with the help of @deecewan, it appears to be an issue with using single precision floats as 9999999999 cannot be safely represented as a float, so in iOS 9999999999 will end up being 10000000000 which will fmodf to 0.
This _might_ be an issue specific to targeting non-64-bit architectures as the reanimated code looks to be using doubles, but CGFloat might downcast to a 32-bit float.
yeah, from here it looks like if you're targeting a 32-bit architecture, CGFloat downcasts to a float instead of a double 馃槥
Hi @lebedev,
thanks for the detailed description.
We use CGFloat in Operator node code and it downcasts to floats as @deecewan mentioned. We should use there plain double like in Android implementation. I'll prepare a PR.
Thanks!
Most helpful comment
Hi @lebedev,
thanks for the detailed description.
We use
CGFloatin Operator node code and it downcasts to floats as @deecewan mentioned. We should use there plaindoublelike in Android implementation. I'll prepare a PR.Thanks!