Search code examples
mathintegersignedunsigned-integer

Convert signed to unsigned integer mathematically


I am in need of an unsigned 16 bit integer value in my OPC server but can only send it a signed 16 bit integer. I need to change this signed integer to unsigned mathematically but am unsure how. My internet research has not lead me in the right path either. Could someone please give some advise? Thanks in advance.


Solution

  • Mathematically, the conversion from signed to unsigned works as follows: (1) do the integer division of the signed integer by 1 + max, (2) codify the signed integer as the non-negative remainder of the division. Here max is the maximum integer you can write with the available number of bits, 16 in your case.

    Recall that the non-negative remainder is the only integer r that satisfies

      1. s = q(1+max) + r
      2. 0 <= r < 1+max.
    

    Note that when s >= 0, the non-negative remainder is s itself (you cannot codify integers greater than max). Therefore, there is actually something to do only when s < 0:

    if s >= 0 then return s else return 1 + max + s
    

    because the value r = 1 + max + s satisfies conditions 1 and 2 above for the non-negative reminder.

    For this convention to work as expected the signed s must satisfy

    - (1 + max)/2 <= s < (1 + max)/2
    

    In your case, given that you have 16 bits, we have max = 0xFFFF and 1 + max = 0x10000 = 65536.

    Note also that if you codify a negative integer with this convention, the result will have its highest bit on, i.e., equal to 1. This way, the highest bit becomes a flag that tells whether the number is negative or positive.

    Examples:

     2 -> 2
     1 -> 1
     0 -> 0
    -1 -> 0xFFFF
    -2 -> 0xFFFE
    -3 -> 0xFFFD
    ...
    -15 -> 0xFFF1
    ...
    -32768 -> 0x8000 = 32768 (!)
    -32769 -> error: cannot codify using only 16 bits.