I’m working in a language that can only do binary math on 16-bit numbers but I need to use binary math on 32-bit values so I have to make some of my own functions. For example, I implemented binary OR as:
_32bit_or(a,b){
var{
a1=round(a/(2**16));
a2=a%(2**16);
b1=round(b/(2**16));
b2=b%(2**16);
}
.=((a1|b1) * (2**16)) + (a2|b2);
}
Split the 32-bit value into two 16-bit portions, OR each portion, and recombine. Simple enough.
But I now need to implement shifting which isn’t as easy because by breaking the numbers apart, shifting, and then recombining, I’m losing bits! What I tried was:
_32bit_rshift(a,b){
var{
a1=round(a/(2**16));
a2=a%(2**16);
}
. = ((a1>>b) * (2**16)) + (a2>>b)
}
But this of course doesn’t work as I mentioned. Can anyone provide some input?
For a left shift 1, shift the upper word, AND the lower word with 0x8000 and OR the upper result with 1 if the result of the AND is not 0, then shift the lower word.
For a right shift 1, shift the lower word, AND the upper word with 1 and OR the lower result with 0x8000 if the result of the AND is not 0, then shift the upper word.
Shifting by more than one bit requires larger values to AND with and appropriate shifting before ORing.