Search code examples
c#ftdi

c# FTDI 24bit two's complement implement


I am a beginner at C# and would like some advice on how to solve the following problem:

My code read 3 byte from ADC true FTDI ic and calculating value. Problem is that sometimes I get values under zero (less than 0000 0000 0000 0000 0000 0000) and my calculating value jump to a big number. I need to implement two's complement but I and I don't know how.

byte[] readData1 = new byte[3]; 
ftStatus = myFtdiDevice.Read(readData1, numBytesAvailable, ref numBytesRead); //read data from FTDI
int vrednost1 = (readData1[2] << 16) | (readData1[1] << 8) | (readData1[0]); //convert LSB MSB
int v = ((((4.096 / 16777216) * vrednost1) / 4) * 250); //calculate 

Solution

  • Convert the data left-justified, so that your sign-bit lands in the spot your PC processor treats as a sign bit. Then right-shift back, which will automatically perform sign-extension.

    int left_justified = (readData[2] << 24) | (readData[1] << 16) | (readData[0] << 8);
    int result = left_justified >> 8;
    

    Equivalently, one can mark the byte containing a sign bit as signed, so the processor will perform sign extension:

    int result = (unchecked((sbyte)readData[2]) << 16) | (readData[1] << 8) | readData[0];
    

    The second approach with a cast only works if the sign bit is already aligned left within any one of the bytes. The left-justification approach can work for arbitrary sizes, such as 18-bit two's complement readings. In this situation the cast to sbyte wouldn't do the job.

    int left_justified18 = (readData[2] << 30) | (readData[1] << 22) | (readData[0] << 14);
    int result18 = left_justified >> 14;