I see I was pretty wrong with my old answer, so I wrote this trivial loop which checks for int
overflow:
long s1 = 0xffff, s2 = 0xffff;
for (int n=0; ; ++n) {
final int a = 0xff;
final int b = 0xff;
final int x = (a << 8) | b;
s2 += s1 += x;
System.out.format("%4d %08X %08X\n", n, s1, s2);
if ((s2 & 0xFFFFFFFFL) != s2) break;
}
The output ends with
358 0167FE98 FDD3022C
359 0168FE97 FF3C00C3
360 0169FE96 100A5FF59
which shows us that we must stop before the 360th iteration in order for s2
not to overflow.
There's one difference to the presented algorithm. The line
return (s2 << 16) | s1;
should read
return (s2 << 16) | (s1 & 0xffff);
as the original type is uint16_t
, but this doesn't matter, because of s1
being small.