2s complement conversion

Hi
I have data that is in bytes
I can convert the bytes to integer
I can join 2 bytes to get a word and convert it to unsigned interger
BUT please help as to how I get the signed integer, I have seen it as 2s complement ???

My simple simple testing code is as below:
THANKS
byte testbyte=254;//(FE in HEX)
int signedINTword=0;
void setup() {
Serial.begin(115200);delay(2000);
signedINTword = word(testbyte, testbyte); // (FEFE in HEX)
Serial.println(valueH);
}
the result is 65278 which is technically correct (for unsigned integer)

how do I get the result in signed Integer
also called 2s complement ???
It will then be -258
Thanks

You combine two bytes in one variable (signedINTword), but than put to print another variable valueH
Try to print exactly what you combined. It works.

THANKS but I need the value to use for statistics.
The "answer: is the signed value of the word.

I only joined these bytes as an example.

Untested:
int result = int((testbyte << 8) | testbyte);


void setup()
{
  Serial.begin(115200);
  test(32000);
  test(-59);
}

void loop()
{
}

void test(int x)
{
  Serial.print("input int  : ");
  Serial.println(x);
  byte lo = lowByte(x);
  byte hi = highByte(x);
  Serial.print("low byte   : ");
  Serial.println(lo);
  Serial.print("high byte  : ");
  Serial.println(hi);
  int y = hi << 8;
  y = y | lo;
  Serial.print("output int : ");
  Serial.println(y);
  Serial.println();
}

@arduinodumbo
As I said, you just printed incorrect variable.
Your code is correct. It works fine for me.
Print what you conversed

byte testbyte=254;//(FE in HEX)
int signedINTword=0;
void setup() {
Serial.begin(115200);delay(2000);
signedINTword = word(testbyte, testbyte); // (FEFE in HEX)
Serial.println(signedINTword );
}

This printed -258 - exact what you want!

What is the valueH at all? It doesn't declared in your code.

Try

int16_t signedINTword=0;

And please tell us what type of arduino you are using, because 'int' is 2 bytes on some Arduino and 4 bytes on others.

you don't need to do anything

first consider what happens if you subtract 1 from a 2 byte signed variable having a value of zero, 0x0000. it underflows, becoming 0xffff. the most significant bit of a "signed" variable indicates its sign and 0xffff is the 2s complement value for -1. subtracting 1 again results in 0xfffe, -2 and so forth

consider subtracting 5 from a 2 byte signed variable with a value of 2. the variable starts with a value of 0x0002 and becomes 0xfffd which represent -3 in 2s complement.

similarly, if you add 6 to a 2 byte variable containing 0xfffd, it naturally overflows, and becomes 0x0003 which is now positive

this is the beauty of math

Hi
THANKS for your answers
SORRY, my bad, valueH was from a previous version and I missed it when reducing the code size.

Is it code works now?

Hi
I am still trying to convert from a word (2 bytes) to decimal.

I have a script that works but need to make the HEX value a variable not coded into the script

void setup() {
Serial.begin(115200);delay(5000);
}
void loop() {
Serial.println(hex2int("ff18"));// returns -232 (minus)    ***** "ff18" needs to be a variable please  *****
//Serial.println(hex2int("00e8"));// returns +232 (plus)
delay(5000);
}


int16_t hex2int(const char *hex)
{
uint16_t value; // unsigned to avoid signed overflow
for (value = 0; *hex; hex++) {
value <<= 4;
if (*hex >= '0' && *hex <= '9')
value |= *hex - '0';
else if (*hex >= 'A' && *hex <= 'F')
value |= *hex - 'A' + 10;
else if (*hex >= 'a' && *hex <= 'f')
value |= *hex - 'a' + 10;
else
break; // stop at first non-hex digit
}

Please do us all a favour by Auto formatting your code in the IDE and posting it here in < CODE/ > tags like this

void setup()
{
  Serial.begin(115200);
  delay(5000);
}
void loop()
{
  Serial.println(hex2int("ff18"));// returns -232 (minus) ***** "ff18" needs to be a variable please *****
  //Serial.println(hex2int("00e8"));// returns +232 (plus)
  delay(5000);
}

int16_t hex2int(const char *hex)
{
  uint16_t value; // unsigned to avoid signed overflow
  for (value = 0; *hex; hex++)
  {
    value <<= 4;
    if (*hex >= '0' && *hex <= '9')
      value |= *hex - '0';
    else if (*hex >= 'A' && *hex <= 'F')
      value |= *hex - 'A' + 10;
    else if (*hex >= 'a' && *hex <= 'f')
      value |= *hex - 'a' + 10;
    else
      break; // stop at first non-hex digit
  }
}

Note how much easier to read it is than your original post

Note too that I added the missing } at the end of the posted code

OK but not sure how to

Edit your first post using the :pencil2: in the tool bar just below your post

select the code part and press the <code/> icon in the tool bar to mark it as code. (also make sure you indented the code in the IDE before copying, that’s done by pressing ctrlT on a PC or cmdT on a Mac)

➜ do yourself a favour and please read How to get the best out of this forum


If your 2 byte thingy is in a variable already, just print it. You’ll see it in decimal (DEC is the default - not needed) or add that you want it in hexadecimal (HEX) or binary (BIN)

uint16_t var = 0xff18;
Serial.print(var);      // in decimal
Serial.print(var, HEX); // in hexadecimal 

Or Is your question about how to enter the string ?

Your two or more topics on the same or similar subject have been merged.

Please do not duplicate your questions as doing so wastes the time and effort of the volunteers trying to help you as they are then answering the same thing in different places.

Please create one topic only for your question and choose the forum category carefully. If you have multiple questions about the same project then please ask your questions in the one topic as the answers to one question provide useful context for the others, and also you won’t have to keep explaining your project repeatedly.

Repeated duplicate posting could result in a temporary or permanent ban from the forum.

Could you take a few moments to Learn How To Use The Forum

It will help you get the best out of the forum in the future.

Thank you.

hex2int is missing a return value; statement.

Why this is treated as a warning and not an error, is beyond me.

Added:

int16_t hex2int(const char *hex)
{
  uint16_t value; // unsigned to avoid signed overflow

Why are the types different?

long debate...

see this for example
43943 – "warning: no return statement in function returning non-void" should be an error
or
109364 – Missing return statement in a non void function gives only a warning but produces a forced crash.

one commet reads as this:

The point being that it's undefined behaviour to /return/ from such a function, not to /write/ such a function.

in the second link there is this

There are programs that are valid and must not give an error.

    int f() { }
    int main() { }

This never calls f() so there is no problem. -Werror=return-type would fail to compile this valid program.

    int g(bool b) { if (b) return 1; }
    int main() { g(true); }

This program calls g(true) which is OK, it never calls g(false). -Werror=return-type would fail to compile this valid program.

The C++ standard says these programs must be accepted without errors. What GCC does is allow you to compile broken code, but it warns, and since GCC 13 it tries to prevent completely unpredictable undefined behaviour if you accidentally do fall off the end of a function without returning.

so kinda makes sense but UB means UB...
:man_shrugging:

Your code (hex2int()) is not for convert two bytes to word - it do conversion from four-char string instead!

Please state clearly what you need exactly. Is you input variable is string "FF18" ox two bytes 0xFF and 0x18 ? Do you understand the difference?

Thanks
I have checked again and valueH was to test if I could get a value from the raw word but t it gave nothing visiable.

You still ignore the questions.

What is the "raw word" in your meaning??? Is it a four char string or two bytes???