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