Rethinking my earlier post about dealing with a left-justified, less-than-16-bit signed integer: you want a general method of managing that value. Specifically, you want something that doesn't rely on the size of an integer for any particular platform. Not a bad idea, if you want to be able to port an application to the Arduino Due, with its 32-bit integers.
If you want that particular generality - if that's not an oxymoron - I don't see a way to avoid examining the sign bit, and then doing something to the data. You can do that as described previously in this post:
tmd3:
I'll note that you can avoid the 6-bit shift by folding the shift operation into the floating-point multiplication, like this:
const long deviceBits = 10;
const long deviceWordLength = 16;
const long deviceMask = -(1 << (deviceWordLength - 1));
const float deviceScaleFactor = 0.25;
int x;
...
if (x & deviceMask) {
x |= deviceMask;
}
someFloatVariable = x * (deviceScaleFactor * (1.0/(1 << (deviceWordLength-deviceBits))));
It has the same advantages as the version in the post referenced above. I think - but don't know - that it will eliminate the 6-bit shift from the compiled code, because the compiler will recognize the factor in the last statement as being composed entirely of constants, and will do that calculation at compile time. It adds a characteristic of the sensor to the code - 0.25 degrees C per tick - but that was already embedded in the program, and it might as well be at the top where it's easy to find and modify. It also adds the characteristic that the device output is a 16-bit word.
I've tested that code with the characteristics of the device described, and I think it works. I haven't tested it with other characteristics to verify its general-ness.
Using the stimmer-fungus technique described above, the general code might look like this:
const long deviceBits = 10;
const long deviceWordLength = 16;
const long deviceMask = (1 << deviceBits) - 1;
const float deviceScaleFactor = 0.25;
int x;
...
x >>= (deviceWordLength-deviceBits);
x += 1 << (deviceBits - 1);
x &= deviceMask;
x -= 1 << (deviceBits - 1);
someFloatVariable = x * deviceScaleFactor;
That code works in the specific case, too. It's not checked for generality.
For more complete generality, you could add a const someType deviceOffset, to manage gizmos whose output values aren't centered on zero. That might be the input code that corresponds to a zero reading, in which case the constant would be int and added to x, or it might be the reading that a zero input describes, in which case the constant would be float and added to someFloatVariable. Then, with just a couple of value changes to constants, you could get your readings in, say, Kelvin, or - oh joy of joys - Farenheit or Rankine; or, you could get your readings from an analog conversion on something like a 4-20mA temperature transducer, or a single-supply LM35 circuit.