Back to main page

Challenges - can you beat this?


Back to main page

Contents

Comments or questions? E-mail: info@sirrida.de


(To top) Signed average rounded toward zero

Who can find a shorter method of calculating the average of two signed 32 bit numbers in 32 bit x86 assembler?
Assuming unlimited intermediate values, the result shall be (a+b)/2, correctly rounded toward zero.
There shall be no division instruction and no restrictions on the parameter's number range.
Preferably the parameters are eax and edx, and the result in eax.
My best solution thus far (only 5 instructions, 15 bytes, developed 2009-06-14):

add eax,edx
setl dl
shrd eax,edx,1
adc dl,-2
adc eax,0

The last two lines are responsible for the correct rounding of negative numbers. If you leave them out the result will be (a+b)>>1 (arithmetic shift), i.e. rounded toward -∞.
I know that this snippet is not necessarily the fastest possible.


Another solution is smaller and probably much faster (6 instructions, only 12 bytes, developed 2013-10-01):

xor ecx,ecx
add eax,edx
setnl cl
dec ecx
sub eax,ecx
rcr eax,1

The credit mainly goes to Black Pete. It is a pity that the setcc commands are to unflexible. My proposed extension to setcc could eliminate the xor and the dec and would lead to a solution of only 4 instructions and only 9 bytes.


You may bookmark this page as http://programming.sirrida.de?challenges.html.
Last change: 2013-10-01