1

I transmit a byte that's always less than 127 with a 1 bit flag to the client by ORing the byte with 0x80.

On the client side, in JavaScript, I have an Array() of numbers representing the bytes of the message (yes it's probably dumb but I haven't figured out typed arrays yet).

Everything works fine until I hit a number with the highest bit of the lowest byte set.

Number:    0011 0101
  flag:    1000 0000
           ---------
           1011 0101


Stored as
integer in   ???
JavaScript

How can I retrieve the original byte (with the highest bit set to 0), plus the flag (denoted by the value of the highest bit)?

EXAMPLE:

(server)
byte x = 90
x | 0x80
> -38

(client - JavaScript)
var x = -38
x ^ 0x80
> -166

How do I get 90 back?

EDIT - I discovered this was due to another bug in my code... I wasn't going crazy with the encoding... sorry all...

5
  • Sorry, don't fully understand the question. Am I right in thinking you simply are trying to "split" the single byte into a 7-bit value and a 1-bit value? Commented Oct 24, 2013 at 9:29
  • Yes but it's not a byte anymore, it's some kind of JavaScript number. XORing with 0x80 still results in negative numbers. Commented Oct 24, 2013 at 9:32
  • 1
    Can you show the code that produces the negative number? This works for me: num = parseInt('10110101', 2) ^ 0x80 and flag = parseInt('10110101', 2) & 0x80 !== 0 Commented Oct 24, 2013 at 9:36
  • I've added an example to explain the problem. Thanks guys.... Commented Oct 24, 2013 at 9:52
  • Try -38 & 0xFF ^ 0x80 instead. See my answer for more details: stackoverflow.com/a/19562701/783743 Commented Oct 24, 2013 at 10:21

3 Answers 3

1

Try the following in JavaScript:

var received = -38;
var adjusted = received & 0xFF; // 218
var original = adjusted ^ 0x80; // 90

That should solve your problem.

Explanation: All numbers in JavaScript stored in the double-precision floating point format:

Bitwise operators however can't deal with floating point numbers. Hence they convert their operands into 32-bit signed integers. [source]

-38 = 11111111 11111111 11111111 11011010

Hence if you do -38 ^ 0x80 you get the wrong answer as only the 8th bit from the right is set to 0. You need to first limit -38 to 8-bits before xoring it with 0x80. Only the least significant byte (i.e. 11011010) is needed. Hence we do -38 & 0xFF to get the least significant byte.

Now that you have the correct byte you may simply xor it with 0x80.

TLDR: Use byte & 0xFF ^ 0x80.

Sign up to request clarification or add additional context in comments.

Comments

0

Not sure I understand the question, but I will give a shot: you have just to XORing the 0x80:

var received = 181; // 10110101
var num = received ^ 0x80;

console.log(num); // 53, 00110101

If you have a different result, probably there is something different in your code – if you run the code above, should give the expected result.

Comments

0

I'm not seeing a problem.

Here is some code I've written to test, with JSFiddle live demo

var val = 57;
var flag = 1;

var valWithFlag = val | (flag ? 0x80 : 0);
var newVal = (valWithFlag & 0x7F);
var newValFlag = (valWithFlag & 0x80 ? 1 : 0);

alert("Val: " + val.toString() + "\n" + 
      "Flag: " + flag.toString() + "\n" +
      "Val With Flag: " + valWithFlag.toString() + "\n" + 
      "New Val Without Flag: " + newVal.toString() + "\n" + 
      "New Val Flag: " + newValFlag.toString() + "\n");

It is giving the desired results...

Val: 57
Flag: 1
Val With Flag: 185
New Val Without Flag: 57
New Val Flag: 1

UPDATE based on extra details provided by the OP

I think this is probably due to integers in javascript being held either as 32 or 64 bit values... so when you pass through -38 to javascript it isn't being held in the same way as the single byte on your server.

You need to convert that -38 into an 8-byte...

var val = -38;
var jsVal = (val & 0xFF);

Which should give you your 90 value to work with. Here is an updated JSFiddle

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.