Search code examples
cunsignedsignedmplab

How to convert unsigned to signed char (and back) while preserving range in C?


I have a situation where I need to convert an unsigned char (0-255) to a signed char (-128-127). I want to have 0 converted to -128, 127 converted to 0 and 255 converted to 127.

I currently am using this code to do this (even though it won't preserve the range entirely):

unsigned char ConvertUnsigned(char n) {
    return n + 127;
}

char ConvertSigned(unsigned char n) {
    return n - 127;
}

This code appears to be taking all values and converting them to 255, but I can't verify this (see below).

I am writing this for the Vex PIC microcontroller (which has a Microchip PICmicro PIC18F8520) using the MPLAB C18 compiler. I can't tell what the code is actually doing because I have no debugger or any other way to communicate with the my code on the chip.

The compiler only supports C89 and also does not automatically promote operands to ints (see the manual, section 2.7.1) like normal C compilers, which might be part of the problem.

Update

The application I am writing works basically like this:

  1. Get an unsigned char that represents a joystick axis (255 = full forward, 0 = full backward, center = ~127/128 [the documentation does not state what it is specifically])
  2. Convert it to a char using ConvertSigned(n)
  3. Do some math to calculate a motor speed (I have eliminated this step for testing).
  4. Convert it back to an unsigned char for the motor (same range as the joystick, except the documentation explicitly states that the center value is 127), using ConvertUnsigned(n).

Solution

  • I think you want:

    unsigned char ConvertUnsigned(char n) {
        return (int)n + 128;
    }
    
    char ConvertSigned(unsigned char n) {
        return (int)n - 128;
    }
    

    assuming "127 converted to 0" is a typo.