Reputation: 1246
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...
Upvotes: 1
Views: 1837
Reputation: 74204
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
.
Upvotes: 1
Reputation: 19953
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
Upvotes: 0
Reputation: 25322
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.
Upvotes: 0