Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

DZone's Guide to

# Compute A 16-bit Sum With Carry

·
Free Resource

Comment (0)

Save
{{ articles[0].views | formatCount}} Views

/**************************************************************************/
/*                     compute a 16-bit sum with carry                    */
/*   nice feature of sum with carry is that it is byte order independent  */
/*       carry from hi-bit of one byte goes into lo-bit of other byte     */
/*   NOTE: assumes data in buf is in net format                           */
/**************************************************************************/

u_short
xsum(buf,len)
char     *buf;
int      len;
{
register u_short   *sp;
register int       slen;
register u_long    sum;        /* >= 32-bit space to keep sum */
union { u_short s; u_char c[2]; } xun;
int                unaligned;

sum = 0;

unaligned = ((unsigned long)buf) & 0x1;
/* If buffer isn't short aligned, need to get fisst byte */
if (unaligned != 0) {
xun.s = 0;
xun.c[1] = buf[0];
sum = xun.s;
buf++; len--;
}
slen = len/2;            /* length in shorts */

/* LINT NOTE: next line has possible ptr alignment message, even
though we've made sure that buf is aligned */
for(sp = (u_short *)buf; slen > 0; slen--,sp++) {
sum += *sp;
}

/* is there a trailing odd byte? */
if ((len & 0x1) != 0) {
#ifdef DEBUG
printf("xsum extra: 0x%X (sum: 0x%X, len %d.)\n", buf[len-1], sum, len);
#endif
xun.s = 0; xun.c[0] = buf[len - 1];
sum += xun.s;
}

/* Fold in all the carries to get a single 16 bit value */
sum = (sum & 0xFFFF) + (((unsigned long)(sum & 0xFFFF0000))>>16);
if (sum > 0xFFFF)
{ sum = (sum & 0xFFFF) + 1; }

if (unaligned != 0)          /* byteswap */
{ sum = ((sum & 0xFF)<<8) + ((sum & 0xFF00)>>8); }
return (sum);
}

Topics:

Comment (0)

Save
{{ articles[0].views | formatCount}} Views

Opinions expressed by DZone contributors are their own.