# [Solved] Stuck with two's complement

This seem to be a rather odd question..

I've connected an HMC5983 compass via the I2C..

That IC stores the direction measurement in two registers (MSB and LSB).
Together they make up a 16-bit value in 2’s complement form, whose range is 0xF800 to 0x07FF (so says the datasheet).

I do not understand how to approach the conversion from two's complement form to 'normal' numbers..

I've tried to read up on this, but sill cant get it..

So I'd be grateful If somebody could explain :((

The Arduino uses two's complement. Put the two halves of the number into a signed 16-bit integer and you're done.

Pete

el_supremo:
The Arduino uses two’s complement. Put the two halves of the number into a signed 16-bit integer and you’re done.

Pete

You mean something like?

int X_direction = (X_MSB << 8 ) + X_LSB;

On this IC there is also a temperature sensor. Further along in the datasheet there is explanation on how to convert it readings from two’s complement to ‘normal’: Temperature = (MSB * 2^8 + LSB) / (2^4 * 8) + 25 in C
Retrieval of temperature conversion works fine, I’m getting right result (around 27 degrees Celsius).

You have to use code tags to prevent the silly emoticons. Two's complement is a useful format for temperatures because they can be negative (minus zero). Changing that would destroy any temperatures below zero.

Yes, that make sense - temperature can indeed have a negative value.

In other words - how to convert something 1111111111100111 to -25?
0b1111111111100111 stands for 65511, but it should be -25 in two's complement..

Store it in a 16-bit signed integer and it will be -25.
Best to declare the integer variable as int16_t so that it will be signed 16-bits even on a 32-bit processor such as Due or Teensy 3.

Pete

Thank you El_supremo!

Declaring variables as int16_t indeed solved it!

AlfaOmega:
In other words - how to convert something 1111111111100111 to -25?

Use Serial.print(). 