I have encountered this function:
const LIMIT32 = 2147483648; // The limit at which a 32-bit number switches signs == 2 ^ 31
function long(v) {
// Two's complement
if (v >= LIMIT32) {
v = -(2 * LIMIT32 - v);
}
return [(v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF];
}
// e.g.
[-3, -2, -1, 0, 1,
-2147483649,-2147483648,-2147483647,
2147483647,2147483648,2147483649].forEach(x =>
console.log(`${x}: ${long(x)}`)
);
I'm wondering generally what this function is doing (why it's returning an array, and what the array elements are).
Then I'm wondering why it takes the v and does what looks like a sign flip and some multiplication.
Finally, the meaning of the bitshift and & operations for each item, why it's as multiples of 8, and why they chose 0xFF.
I'm wondering generally what this function is doing (why it's returning an array, and what the array elements are).
It returns an array of the 4 bytes that make up a int32 value. Why someone wrote the code to do that? I don't know.
Then I'm wondering why it takes the v and does what looks like a sign flip and some multiplication.
Because that's how int32 works: 0x7FFFFFFF + 1 === -0x80000000.
Although it is unnecessary in this code, the bit operations will take care of everything.
Finally, the meaning of the bitshift and & operations for each item, why it's as multiples of 8, and why they chose 0xFF.
Getting the distinct bytes of the int32, each one 8 bit long.
Related
I tried this sort of implementation, but it doesn't appear to be working.
function urs32(n, amount) {
const mask = (1 << (32 - amount)) - 1
return (n >> amount) & mask
}
function flip32(n) {
const mask = (1 << 32) - 1
return ~n & mask
}
log(~0b10101010 >>> 0, urs32(~0b10101010, 0))
log(~0b10101010 >>> 0, flip32(0b10101010))
function log(a, b) {
console.log(a.toString(2), b.toString(2))
}
I would expect for a to equal b in both cases, if done right. Basically I am trying to flip 32-bits (so 1's become 0s, 0's become 1s). I see that 1 << 32 === 0, so to get the value, I do 2 ** 32, but still doesn't work.
How do you implement the equivalent of ~n >>> 0 on a BigInt?
Basically what I am trying to do is create the countLeadingOnes functions (out of the countLeadingZeroes functions), like so:
const LEADING_ZERO_BIT_TABLE = makeLeadingZeroTable()
function makeLeadingZeroTable() {
let i = 0
const table = new Uint8Array(256).fill(0)
while (i < 256) {
let count = 8
let index = i
while (index > 0) {
index = (index / 2) | 0
count--
}
table[i] = count
i++
}
return table
}
function countLeadingZeroes32JS(n)
{
let accum = LEADING_ZERO_BIT_TABLE[n >>> 24];
if (accum === 8) {
accum += LEADING_ZERO_BIT_TABLE[(n >>> 16)]
}
if (accum === 16) {
accum += LEADING_ZERO_BIT_TABLE[(n >>> 8)]
}
if (accum === 24) {
accum += LEADING_ZERO_BIT_TABLE[ n ]
}
return accum;
}
function countLeadingZeroes16JS(n)
{
let accum = LEADING_ZERO_BIT_TABLE[n >>> 8]
if (accum === 8) {
accum += LEADING_ZERO_BIT_TABLE[n]
}
return accum;
}
function countLeadingZeroes8JS(n)
{
return LEADING_ZERO_BIT_TABLE[n]
}
console.log('countLeadingZeroes32JS', countLeadingZeroes32JS(0b10100010001000100010001000100010))
console.log('countLeadingZeroes32JS', countLeadingZeroes32JS(0b00100010001000100010001000100010))
console.log('countLeadingZeroes32JS', countLeadingZeroes32JS(0b00000010001000100010001000100010))
console.log('countLeadingZeroes16JS', countLeadingZeroes16JS(0b1010001000100010))
console.log('countLeadingZeroes16JS', countLeadingZeroes16JS(0b0010001000100010))
console.log('countLeadingZeroes16JS', countLeadingZeroes16JS(0b0000001000100010))
console.log('countLeadingZeroes16JS', countLeadingZeroes16JS(0b0000000000100010))
console.log('countLeadingZeroes8JS', countLeadingZeroes8JS(0b10100010))
console.log('countLeadingZeroes8JS', countLeadingZeroes8JS(0b00100010))
console.log('countLeadingZeroes8JS', countLeadingZeroes8JS(0b00000010))
function countLeadingOnes32JS(n) {
return countLeadingZeroes32JS(~n >>> 0)
}
function countLeadingOnes16JS(n) {
return countLeadingZeroes16JS(~n >>> 0)
}
function countLeadingOnes8JS(n) {
return countLeadingZeroes8JS(~n >>> 0)
}
console.log('countLeadingOnes32JS', countLeadingZeroes32JS(0b00100010001000100010001000100010))
console.log('countLeadingOnes32JS', countLeadingZeroes32JS(0b11100010001000100010001000100010))
console.log('countLeadingOnes32JS', countLeadingZeroes32JS(0b11111100001000100010001000100010))
console.log('countLeadingOnes16JS', countLeadingOnes16JS(0b0100001000100010))
console.log('countLeadingOnes16JS', countLeadingOnes16JS(0b1111110000100010))
console.log('countLeadingOnes16JS', countLeadingOnes16JS(0b1111111111000010))
console.log('countLeadingOnes8JS', countLeadingOnes8JS(0b01000010))
console.log('countLeadingOnes8JS', countLeadingOnes8JS(0b11000010))
console.log('countLeadingOnes8JS', countLeadingOnes8JS(0b11111100))
But it appears that ~n >>> 0 doesn't work on 32-bit integers. How to get this working properly?
How to implement unsigned right shift for BigInt in JavaScript?
Unsigned right-shift is difficult to define meaningfully for arbitrary-size integers, so before you (or anyone) can implement it, you'll have to decide how you want it to behave.
That said, considering the rest of this question, I don't see why you would even need this.
I would expect for a to equal b in both cases
Why would it? Unsigned right-shift and bit flipping are different operations and produce different results.
I see that 1 << 32 === 0
Nope, 1 << 32 === 1. JavaScript (like x86 CPUs) performs an implicit &31 on the shift amount, so since 32 & 31 === 0, ... << 32 is the same as ... << 0.
How do you implement the equivalent of ~n >>> 0 on a BigInt?
The equivalent of ~n is ~n. (That's not a typo. It's literally the same thing.)
The equivalent of ... >>> 0 is BigInt.asUintN(32, ...). (Note that neither the Number version nor the BigInt version shifts anything, so this doesn't answer your headline question "how to implement USR for BigInt".)
it appears that ~n >>> 0 doesn't work on 32-bit integers.
It sure does work. In fact, it only works on 32-bit integers.
The >>> 0 part is completely unnecessary though, you could just drop it.
The reason why this line:
console.log('countLeadingOnes32JS', countLeadingZeroes32JS(0b00100010001000100010001000100010))
isn't producing the number of leading ones is because the function it's calling is ...Zeroes...; an apparent copy-paste bug.
The reason why countLeadingOnes16JS isn't working correctly is because ~ in JavaScript always flips 32 bits. Since a 16-bit number's 32-bit representation has (at least) 16 leading zeros, those all become ones after flipping, and countLeadingZeroes16JS gets an input that's far bigger than it can handle: LEADING_ZERO_BIT_TABLE[n >>> 8] looks up an element that doesn't exist in the table, because the result of n >>> 8 is a 24-bit number in this case, not an 8-bit number. The solution is to use a mask after flipping; a valid implementation of clo16 might be:
function countLeadingOnes16(n) {
return countLeadingZeroes16(~n & 0xFFFF);
}
No BigInts and no >>> 0 required.
countLeadingOnes8 is similar.
You may want to read https://en.wikipedia.org/wiki/Two%27s_complement (or some other description of that concept) to understand what's going on with bitwise operations on negative numbers.
You may also want to learn how to debug your own code. There's a range of techniques: for example, you could have:
inserted console.log statements for intermediate results,
or stepped through execution in a debugger,
or simply evaluated small snippets in the console,
any of which would have made it very easy for you to see what's happening on the path from input number to end result.
For anyone else reading this: there's Math.clz32, which is highly efficient because it gets compiled to a machine instruction, so implementing countLeadingZeros by hand is unnecessary and wasteful. For smaller widths, just subtract: function clz8(n) { return Math.clz32(n) - 24; }
I'm new to JavaScript and I use Node-Red to read an write from a Database.
I receive from the database an object that contains the status of 8 digital inputs.
Each inputs is represented as a bit.
I'm looking for a method to combine each bits into a byte.
This is the object that I receive from the database:
array[1]
0: object
idx: 10
ts: "2018-11-21T06:12:45.000Z"
in_0: 1
in_1: 1
in_2: 1
in_3: 1
in_4: 1
in_5: 1
in_6: 1
in_7: 1
in_x represent the input position.
As out I would like to receive a byte that represent the combination of each single byte.
For example:
in0: 0,
in1: 1,
in2: 0,
in3: 0,
in4: 0,
in5: 1,
in6: 0,
in7: 0,
The output byte will be: 00100001 in binary that converted to byte is 33
Any suggestions?
Thanks in advance.
The following code works as you requested*:
var output =
arr[0].in_0 +
(arr[0].in_1 << 1) +
(arr[0].in_2 << 2) +
(arr[0].in_3 << 3) +
(arr[0].in_4 << 4) +
(arr[0].in_5 << 5) +
(arr[0].in_6 << 6) +
(arr[0].in_7 << 7);
This code assumes that each variable can only be a 1 or a 0. Anything else will result in nonsense.
I have used the Left Bit Shift operator (<<) to obtain the power of two for each on bit.
You have specified that in_7 is the Most Significant Bit. If it is actually the Least Significant Bit, reverse the order of the in_x variables.
*The result is not a byte, but it does contain the number that I think you're expecting.
Is it possible to get the integers that, being results of powers of two, forms a value?
Example:
129 resolves [1, 128]
77 resolves [1, 4, 8, 64]
I already thought about using Math.log and doing also a foreach with a bitwise comparator. Is any other more beautiful solution?
The easiest way is to use a single bit value, starting with 1 and shift that bit 'left' until its value is greater than the value to check, comparing each bit step bitwise with the value. The bits that are set can be stored in an array.
function GetBits(value) {
var b = 1;
var res = [];
while (b <= value) {
if (b & value) res.push(b);
b <<= 1;
}
return res;
}
console.log(GetBits(129));
console.log(GetBits(77));
console.log(GetBits(255));
Since shifting the bit can be seen as a power of 2, you can push the current bit value directly into the result array.
Example
You can adapt solutions from other languages to javascript. In this SO question you'll find some ways of solving the problem using Java (you can choose the one you find more elegant).
decomposing a value into powers of two
I adapted one of those answers to javascript and come up with this code:
var powers = [], power = 0, n = 129;// Gives [1,128] as output.
while (n != 0) {
if ((n & 1) != 0) {
powers.push(1 << power);
}
++power;
n >>>= 1;
}
console.log(powers);
Fiddle
Find the largest power of two contained in the number.
Subtract from the original number and Add it to list.
Decrement the exponent and check if new 2's power is less than the number.
If less then subtract it from the original number and add it to list.
Otherwise go to step 3.
Exit when your number comes to 0.
I am thinking of creating a list of all power of 2 numbers <= your number, then use an addition- subtraction algorithm to find out the group of correct numbers.
For example number 77:
the group of factors is { 1,2,4,8,16,32,64} [ 64 is the greatest power of 2 less than or equal 77]
An algorithm that continuously subtract the greatest number less than or equal to your number from the group you just created, until you get zero.
77-64 = 13 ==> [64]
13-8 = 7 ==> [8]
7-4 = 3 ==> [4]
3-2 = 1 ==> [2]
1-1 = 0 ==> [1]
Hope you understand my algorithm, pardo my bad english.
function getBits(val, factor) {
factor = factor || 1;
if(val) {
return (val % 2 ? [factor] : []).concat(getBits(val>>1, factor*2))
}
return [];
}
alert(getBits(77));
I am receiving and sending a decimal representation of two little endian numbers. I would like to:
shift one variable 8 bits left
OR them
shift a variable number of bits
create 2 8 bit numbers representing the first and second half of the 16 bit number.
javascript (according to https://developer.mozilla.org/en/JavaScript/Reference/Operators/Bitwise_Operators) uses big endian representation when shifting...
endianness is a bit foreign to me (I am only 90 percent sure that my outlined steps are what i want.) so swapping is a bit dizzying. please help! I only really need to know how to swap the order in an efficient manner. (I can only think of using a for loop on a toString() return value)
function swap16(val) {
return ((val & 0xFF) << 8)
| ((val >> 8) & 0xFF);
}
Explanation:
Let's say that val is, for example, 0xAABB.
Mask val to get the LSB by &ing with 0xFF: result is 0xBB.
Shift that result 8 bits to the left: result is 0xBB00.
Shift val 8 bits to the right: result is 0xAA (the LSB has "dropped off" the right-hand side).
Mask that result to get the LSB by &ing with 0xFF: result is 0xAA.
Combine the results from steps 3 and step 5 by |ing them together:
0xBB00 | 0xAA is 0xBBAA.
function swap32(val) {
return ((val & 0xFF) << 24)
| ((val & 0xFF00) << 8)
| ((val >> 8) & 0xFF00)
| ((val >> 24) & 0xFF);
}
Explanation:
Let's say that val is, for example, 0xAABBCCDD.
Mask val to get the LSB by &ing with 0xFF: result is 0xDD.
Shift that result 24 bits to the left: result is 0xDD000000.
Mask val to get the second byte by &ing with 0xFF00: result is 0xCC00.
Shift that result 8 bits to the left: result is 0xCC0000.
Shift val 8 bits to the right: result is 0xAABBCC (the LSB has "dropped off" the right-hand side).
Mask that result to get the second byte by &ing with 0xFF00: result is 0xBB00.
Shift val 24 bits to the right: result is 0xAA (everything except the MSB has "dropped off" the right-hand side).
Mask that result to get the LSB by &ing with 0xFF: result is 0xAA.
Combine the results from steps 3, 5, 7 and 9 by |ing them together:
0xDD000000 | 0xCC0000 | 0xBB00 | 0xAA is 0xDDCCBBAA.
Such function can be used to change endianness in js:
const changeEndianness = (string) => {
const result = [];
let len = string.length - 2;
while (len >= 0) {
result.push(string.substr(len, 2));
len -= 2;
}
return result.join('');
}
changeEndianness('AA00FF1234'); /// '3412FF00AA'
Use the << (bit shift) operator. Ex: 1 << 2 == 4.
I really think that the underlying implementation of JavaScript will use whatever endianess the platform it is running on is using. Since you cannot directly access memory in JavaScript you won't ever have to worry about how numbers are represented physically in memory. Bit shifting integer values always yield the same result no matter the endianess. You only see a difference when looking at individual bytes in memory using pointers.
Here is a oneliner for arrays to swap between big and little endian (and vise versa). The swapping is done using reverse on byte level. I guess for large arrays, it is more efficient than looping over scalar swap function.
function swapbyte(x) {
return new Float64Array(new Int8Array(x.buffer).reverse().buffer).reverse()
}
// Example
buf = new ArrayBuffer(16); // for 2 float64 numbers
enBig = new Float64Array(buf);
enBig[0] = 3.2073756306779606e-192;
enBig[1] = 2.7604354232023903e+199;
enLittle = swapbyte(enBig)
// two famous numbers are revealed
console.log(enLittle)
// Float64Array [ 6.283185307179586, 2.718281828459045 ]
// swapping again yields the original input
console.log(swapbyte(enLittle))
// Float64Array [ 3.2073756306779606e-192, 2.7604354232023903e+199 ]
I would like to store all currently-pressed keycodes in a single variable by using bitwise operations when the key is pressed and when the key is released.
I'm not sure how to properly use bitwise operations, but I know this will be very simple to someone who does.
Once complete, it should be simple to see which key is currently depressed by asking "is this key's code in the variable?"
Thanks in advance!
This is technically impossible to do in a single variable, no datatype in javascript can store the 256 bits required to hold the bitmask (which supports bitwise operations), you will need to use an array instead.
Also, unless you have text to speech software which you've macroed to magically execute js functions for you, asking your computer: "is this key's code in the variable?" won't do squat.
The way you would do it would be to initialize an array with 256 indexes, and then when a key is pressed, you find the relevant index and set it to true and when a key is released, you set it to false
It's the only way to do it. There actually isn't any other.
I don't think that it is possible the way you want to do it. Have a look at the available keycodes. There you see, that e.g. backspace is 8 and tab is 9.
In binary, that would be 1000 and 1001. Using binary operators, you would use OR | to "combine" the values, which would result in 1001.
You would check if a value is set via AND &, e.g. 1001 & 1000 to see, if the backspace key was pressed. Unfortunately, this would also evaluate to true if only the tab key was pressed (as its value is 1001).
That said, you can only use such bitwise comparison techniques, if the different values you want to test are powers of 2 only, i.e. 1, 2, 4, 8, 16, 32 and so on, as this represents in binary 1, 10, 100, 1000,...
For example if we can have a status variable and possible statuses would be OPEN = 2, LIGHT ON = 4 and ALARM ON = 8.
Assume that it is OPEN and LIGHT ON, i.e.
0010
| 0100
-------
0110
Here we can easily check whether the ALARM is on, be using AND: 0110 & 1000 = 0. But if we would encode ALARM ON with 6 = 0110, we could not check this.
What you could do is, to map the key codes to a some power of 2 value and apply binary operations there. The Wikipedia article about bitmasks might be worth reading.
I hope my explanation was somehow clear.
javascript bit operations are generally reliable for the first 31 bits, and things go downhill from there. So, you can 31 different keys which you have given a value to act as a flag. for instance, if you wanted to track the four arrows and A and B, you would do something like this.
var KEYS = {
LEFT: 1 << 0,
UP: 1 << 1,
RIGHT: 1 << 2,
DOWN: 1 << 3,
A: 1 << 4,
B: 1 << 5
}
var flags = 0;
myElement.addEventListener ('keydown', function (e) {
switch (e.keyCode) {
case 37: // left
flags = flags | KEYS.LEFT;
break;
case 38: // up
flags = flags | KEYS.UP;
break;
... etc ...
}
}
} , false);
function checkKeys () {
if ( (flags & KEYS.LEFT) === KEYS.LEFT)
alert('LEFT key pressed');
}
if ( (flags & KEYS.UP) === KEYS.UP )
alert('UP key pressed');
}
... etc ...
}
I'm not sure if there is such a thing as a ByteArray in JavaScript but if so, you could do it much like how this fellow did his logic in ActionScript3. While I am a big fan of bitflags & bitwise operations, I don't get the bitshifting he's doing and much of his code is way over my head. I just know it works on as3 projects I've worked on.
Also if you'd like to learn more about bitflags & bitwise operations (aside from the bitshifting) check out this article - http://jwopitz.wordpress.com/2012/02/13/using-bitflags-and-bitwise-math/
Source - https://github.com/richardlord/Asteroids/blob/master/src/no-dependencies/net/richardlord/input/KeyPoll.as
//init the bytearray
_states = new ByteArray();
_states.writeUnsignedInt( 0 );
_states.writeUnsignedInt( 0 );
_states.writeUnsignedInt( 0 );
_states.writeUnsignedInt( 0 );
_states.writeUnsignedInt( 0 );
_states.writeUnsignedInt( 0 );
_states.writeUnsignedInt( 0 );
_states.writeUnsignedInt( 0 );
//on a keydown listener (note the bitwise OR for adding
_states[ event.keyCode >>> 3 ] |= 1 << ( event.keyCode & 7 );
//on a keyup listener (note the bitwise AND plus bitwise NOT
states[ ev.keyCode >>> 3 ] &= ~(1 << (ev.keyCode & 7));
//check for keydown
return ( states[ keyCode >>> 3 ] & (1 << (keyCode & 7)) ) != 0;
//check for keyup
return ( states[ keyCode >>> 3 ] & (1 << (keyCode & 7)) ) == 0;