Sorry, mi ero dimenticato un paio di parentesi; la versione corretta (aggiornata anche sopra) è:
codice:
short rawtoshort(unsigned short raw, unsigned int bits)
{
    unsigned short signmask=1<<(bits-1);
    return ((raw&signmask)?(-(short)signmask):0) + (raw&(signmask-1));
}
http://ideone.com/opeDhp