Extract bits from start to end in javascript - javascript

In Java script I want to extract bits 13 to 16 from integer number.
Example: If I extract bits 13 to 16 from number 16640 then output will be 2
I have searched on google and found few links but they are in C language.

Assuming your bit count starts at 0:
var extracted, orig;
orig = parseInt("16640", 10); // best practice on using parseInt: specify number base to avoid spurious octal interpretation on leading zeroes (thx Ken Fyrstenberg)
extracted = ((orig & ((1 << 16) - 1) & ~(((1 << 13) - 1))) >>> 13);
Explanation:
mask the lower 16 bits of the original number
mask the complement of the lower 13 bits of the result (ie. bits 13-31)
you currently have bits 13-16 of the orignal number in their original position. shift this bit pattern 13 bits to the right.
Note that this method only works reliably for numbers less than 2^31. The docs (MDN) are here

Javascript's bitwise operations work essentially the same way as they do in C:
var bits13to16 = (number >> 13) & 15;
This shifts the number 13 bits to the right (eliminating bits 0-12) and masks all but the last 4 remaining bits (which used to be bits 13-16). 15 = 2^4 - 1.

All suggestions are working but the simplest I think is given by #dandavis.
parseInt( 16640 .toString(2).slice(-16, -13), 2 );

Related

In JavaScript, can bit shifting be used to isolate 1 or more bits in a byte?

In JavaScript code where the 8 bits of a byte represent 8 Boolean "decisions" (aka: flags), there is a need to isolate each given bit for conversion to a Boolean variable. Consider my solution using String parsing:
var bitParser = function (_nTestByte, _nBitOrdinal) {
var bits = ("00000000" + _nTestByte.toString(2)).slice(-8); // convert to binary and zero-pad
return bits[_nBitOrdinal] === "1";
};
console.log(bitParser(0b10100101, 2)); // ECMAScript 6+ prefix, returns true
It works, and shows the desired result. However I have a hypothesis stating that a bit shifting technique would be a faster option than String manipulation. I tend to believe that but desire to prove it.
The problem is, I have yet to produce such a function that works correctly, let alone something I can test. I have created the following logic plan that I believe is accurate:
/*
LOGIC PLAN
----------
0) Remember: all bitwise operators return 32 bits even though we are using 8
1) Left shift until the desired bit is the left-most (highest) position;
2) Right shift (zero filling) 31 bits to eliminate all right bits
*/
The implementation of the login plan follows. Because of the 32 bit nature of bitwise operators, its my belief that the entire left 3 bytes (24 bits) must be shifted off first before we even reach the byte being worked on. Then, assuming a scenario where the 3rd bit from the left (String ordinal 2) is the desired bit, I am shifting off 2 more bits (ordinals 0 & 1), for a total of 26 bits of left shifting.
This should produce a binary number with the desired bit all the way left followed by 31 undesired zero bytes. Right shifting those 31 bits away produces a binary with 31 (now) leading zero bits which evaluates to whatever the value of the desired bit is. But of course, I would not be writing this question if THAT were true, now would I? :-)
// hardcoded, assuming the second "1" (ordinal 2) is the bit to be examined
console.log((0b10100101 << 26) >> 31); // instead of 1, returns -1
I feel like I am really close, but missing something or pushing JavaScript too hard (lol).
In JavaScript code where the 8 bits of a byte represent 8 Boolean "decisions" (aka: flags), there is a need to isolate each given bit for conversion to a Boolean variable...
If that's the actual goal, bitshifting is neither necessary nor useful: Just use a bitwise & with the desired bit, which will give you either 0 or a number with that bit set. 0 is falsy, the number with a bit set is truthy. You can either use that as-is, or force it to boolean via !!flag or Boolean(flag):
Here's your bitParser function using bitmasking:
var bitParser = function (_nTestByte, _nBitOrdinal) {
return !!(_nTestByte & Math.pow(2, _nBitOrdinal));
};
console.log(bitParser(0b10100101, 2)); // true
console.log(bitParser(0b10100101, 1)); // false
Rather than doing the Math.pow every time, of course, we'd probably be better off with a lookup table:
var bits = [
0b00000001,
0b00000010,
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000,
0b10000000
];
var bitParser = function (_nTestByte, _nBitOrdinal) {
return !!(_nTestByte & bits[_nBitOrdinal]);
};
console.log(bitParser(0b10100101, 2)); // true
console.log(bitParser(0b10100101, 1)); // false
From your question I took
console.log((0b10100101 << 26) >> 31); //instead of 1, returns -1.
And to answer your question why it returned -1 instead of 1
You need to do unsigned right shift >>> instead of signed one >>
console.log((0b10100101 << 26 ) >>>31);
Yes it can, and what you're doing is almost correct.
Integers are represented as a 32bit binary number, with the leftmost bit representing the sign (it's 1 if the number is negative and 0 if the number is positive). Lets look at some of the numbers' representations:
//last 31 digits keeps increasing as the number decreases
// ...
-2 => 0b11111111111111111111111111111110
-1 => 0b11111111111111111111111111111111
0 => 0b00000000000000000000000000000000
1 => 0b00000000000000000000000000000001
2 => 0b00000000000000000000000000000010
// ...
// last 31 digits keep increasing as the number increases
Now, what you're having (0b10100101 << 26) should give you 10010100000000000000000000000000, which you'd expect to be a big negative number (because the left-most bit is 1). Then right afterwards, you have >> 31 which you're expecting to strip off all 31 bits and leave you with the left-most bit.
That should work, but it's not what's happening. And why is that? It's because the people who came up with ECMAScript thought it would make more sense if 4 >> 1 returns 2 and -4 >> 1 returns -2.
4 >> 1 // returns 2 which is 0b00000000000000000000000000000010
0b0000000000000000000000000000000100 >> 1 // returns 2, same
-4 >> 1 // returns -2, which is 0b11111111111111111111111111111110
But -4 is 0b11111111111111111111111111111100, and for your purposes right shifting it by 1 should yield 0b01111111111111111111111111111110 (big positive number, since left-post bit is 0), and that's not -2!
To overcome that, you can use the other right shift operator which doesn't care about about the sign: >>>. -4 >>> 1 is 2147483646 which is what we want.
So console.log((0b10100101 << 26) >>> 31); gives you 1, which is what you want. You can also keep using >> and regarding any negative outcome to be a result of 1 being the chosen bit.
The most simple way to achieve your actual need is to use simple conditions rather than trying to isolate bits.
var bitParser = function (_nTestByte, _nBitOrdinal) {
return (_nTestByte & _nBitOrdinal);
};
console.log(bitParser(6, 2) ? true : false); // true
console.log(bitParser(6, 1) ? true : false); // false
I adapted the console.log() expression in a way that may seem complicated.
It's only to really show the logical result at this step, while I didn't choose to use !! inside of the function, so returning a truly/falsy value rather than true|false.
Actually this way keeps all the most simple possible, because the expected use else where in the code is if (bitParser(...)), which automatically casts the result to boolean.
BTW, this works whatever is the _nTestByte size (may be more than 1 byte).

Modulo of 24 digit long integer?

I need to calculate the modulo of a 24 digit long integer (IBAN checksum) but JS calculates wrong.
e.g.:
700901001234567890131400 % 97 = 90
but in JS (V8) it's 38.
How can I calculate the modulo in JS
I think the document you're linking to already says what you should do:
If the application software in use does not provide the ability to handle integers of this size, the modulo operation can be performed in a piece-wise manner.
Piece-wise calculation D mod 97 can be done in many ways. One such way is as follows:
Starting from the leftmost digit of D, construct a number using the first 9 digits and call it N.[Note 3]
Calculate N mod 97.
Construct a new 9-digit N by concatenating above result (step 2) with the next 7 digits of D. If there are fewer than 7 digits remaining in D but at least one, then construct a new N, which will have less than 9 digits, from the above result (step 2) followed by the remaining digits of D
Repeat steps 2–3 until all the digits of D have been processed
The result of the final calculation in step 2 will be D mod 97 = N mod 97.
It might be harder than one can think.
It's quite tricky to ensure javascript handle number as integer (it often store them as float, but not always).
Others already made libraries to handle IBAN check in JS.
Take a look at https://github.com/arhs/iban.js for instance.
The largest number that can be represented in javascript is 2^53 - 1. They are 64-bit floating point values. So the largest number is 9007199254740991.
A number greater than 9007199254740991 can not be caclcuted in normal way. So, to find the modulo of such large number you have to break it into pieces.
eg. 700901001234567890131400 can be broken into 700901001234567 and 890131400.
First find the modulo of 700901001234567.
700901001234567 % 97 = 13
Now join 13 infront of second number 13890131400 and find the modulo of this number
13890131400 % 97 = 90
I came across this problem recently and this looks like what is solvable with Horner's method [https://en.wikipedia.org/wiki/Horner%27s_method]
/**
* str is numeric.
* MOD=97 is our use case
* #return: an integer 0<=x<=97
**/
int getMod(String str, int MOD) {
int remainder = 0;
for(Character c : str.toCharArray()) {
int value = Character.getNumericValue(c);
remainder = 10*remainder + value;
remainder %= MOD;
}
return remainder;
}
Unless I don't fully understand the problem, the code above should work.

Left shifting with a negative shift count in Javascript

A thing which I noticed in Javascript -
a << -1
Returns 0 when a = even.
Returns -2147483648 when a = odd.
Similarly, different values are returned when -1 is changed to some other -ve number.
Can someone explain what bit operations are taking place under the hood ? Or is the behavior undefined ?
Thanks
EDIT
Also shouldn't Zero-fill right shift i.e. -2 >>> 1 return 7 ?
-2 = 1110. After, right shift with zero-fill, it should give 0111 = 7
but
a = -2; console.log(a >>> 1);
returns
2147483647
I too wondered about this which is how I landed here. I’ve done a little research and figured out the behavior. Essentially JavaScript treats the operand and shift value as sequences of bits rather than as numbers. It works with 32 bit integers (floats get truncated) and the maximum shift is 32 bits. If we shift by a number greater than 32, all the bits would shift out, resulting in zero. To ensure the shift is less than or equal to 32, JavaScript truncates the 5 least significant bits [a << (b&0x1F)] or possibly with the modulus method [a << (b%32)] which yields the same result.
With that out of the way, think of the negative number you are shifting by as a sequence of bits, not a negative number (i.e. -1). In this case b = -1 = 0xFFFFFFFF. Since this number is larger than 32, it is truncated 0xFFFFFFFF & 0x1F = 31 or 0xFFFFFFFF % 32 = 31.
So in your example “a" gets shifted all the way from the least significant bit to the most significant bit (the sign bit). Therefor the result of the shift is either 0x00000000 or (0x80000000 = -2147483648) depending on whether the operand had the 1 bit set (odd or even).
Got the answer to the second part of my question i.e. -2 >>> 1 = 7.
Javascript always deals with 32 bits. So when I do -2 >>> 1, what really happens under the hood is -
11111111111111111111111111111110 >>> 1 which gives 01111111111111111111111111111111 = (2147483647)base10
The LeftShift operator adds zeros to the right of the binary representation of a number, shifting the bits to the left. Only the 5 least significant digits of the additive expression are used. So:
var x = 5 // 101
alert( x << 1 ); // 1010 = 10
alert( x << 2 ); // 10100 = 20
alert( x << 3 ); // 101000 = 40
alert( x << 4 ); // 1010000 = 80
alert( x << 64 ); // 101 = 5
The last expression returns 5 as shift only uses the last 5 bits of the the additive expression, which is 1000000 so only the 00000 part is used.

using bitwise OR in javascript to convert to integer

we can do the following to convert:
var a = "129.13"|0, // becomes 129
var b = 11.12|0; // becomes 11
var c = "112"|0; // becomes 112
This seem to work but not sure if this is a standard JS feature. Does any one have any idea if this is safe to use for converting strings and decimals to integers ?
Yes, it is standard behavior. Bitwise operators only operate on integers, so they convert whatever number they're give to signed 32 bit integer.
This means that the max range is that of signed 32 bit integer minus 1, which is 2147483647.
(Math.pow(2, 32) / 2 - 1)|0; // 2147483647
(Math.pow(2, 32) / 2)|0; // -2147483648 (wrong result)

What do "num & 8", "num >> 8" and "num >> 8 & 64" mean in javascript?

I am having a hard time googling because of the symbols.
What do num & 8, num >> 8 and num >> 8 & 64 mean in javascript?
They are bitwise operators
to get the hundreds digit [num]->[/ 100]->[% 10]
To extract bits, use the [&] object to mask out the bit you're interested in, then optionally bit shift with [>>].
For instance, to get bit 3 (counting from right starting with zero) [num]->[& 8]->[>> 3].
If you just want to use the calculation to control a logic object (like if or a ggate), you can skip the bit shift.
These are really not Max-specific questions, they are fundamental DP techniques.
Shift left <<
The following expression means, shift 2 binary numbers to left:
alert( 1 << 2 );
So binary this is (I'll take 8 bit for example), shift the bits to left, 2 places
00000001 = 1
00000010 = 2
00000100 = 4
Shift right >>
The following expression means, shift 2 binary numbers to left:
alert( 255 >> 2 );
So binary this is (I'll take 8 bit for example), shift the bits to right, 2 places
11111111 = 255
01111111 = 127
00111111 = 63
AND operator &
That's the and operator
So you got the following rules:
11110011 = 243
01001111 = 79
01000011 = 67 = RESULT
Which means, only the 1 numbers will stay in the result if both of them have 1's on the same position.

Categories

Resources