I have a byte, and I want to increment bits left to the first bit by 1 (the context is a small Conway's Game of Life).
Example: 11 is 0000 1011:
I want to increment 101
5 + 1 = 6 is 110
reset the first bit to initial state
the byte is now 0000 1101 which is 13
Questions:
Is there a way to make addNeighbour proceed as a void method (I couldn't find a way to not return num)?
Is there a better way to perform addNeighbour operations :
const getBinaryRepresentation = (number) => {
let str = "";
for (let i = 7; i >= 0; i--) {
((number & (1 << i)) != 0) ? str += "1" : str += "0";
}
console.log(str)
}
let num = 5;
getBinaryRepresentation(num) // 0000 0101
const addNeighbour = (num) => {
const isAlive = num & 1;
const neighbours = num >> 1;
num = (neighbours + 1) << 1;
if (isAlive === 1) num |= (1 << 0)
return num;
}
num = addNeighbour(num);
getBinaryRepresentation(num) // 0000 0111
Is there a way to make addNeighbour proceed as a void method (I couldn't find a way to not return num)?
No. If you don't return the result, you cannot assign it back to num. And you cannot pass a reference to the let num (or any other) variable that the function should read from and store into.
Is there a better way to perform addNeighbour operations
Yes. Adding 1 at the second-least significant bit position is just the same as adding 2 at the least signification position. Replace your code with
num += 2;
Put in other terms,
(((num >> 1) + 1) << 1) | (num & 1)
≡ (((num >> 1) << 1) + (1 << 1)) | (num & 1)
≡ ((num & ~1) + (1 << 1)) | (num & 1)
≡ ((num & ~1) | (num & 1)) + (1 << 1)
≡ num + (1 << 1)
Since you can't have byRef on simple values in javascript you can't return void and change variable outside of the function.
You could optimize a little the function though, by reusing variables:
const getBinaryRepresentation = (number) => {
return console.log(number.toString(2).padStart(8, 0));
}
let num = 5;
getBinaryRepresentation(num) // 0000 0101
const addNeighbour = (num) => {
const isAlive = num & 1;
num >>= 1;
num = (num + 1) << 1;
return num | isAlive;
}
num = addNeighbour(num);
getBinaryRepresentation(num) // 0000 0111
Related
In java, you can do something like
UUID id = UUID.fromString("eb66c416-4739-465b-9af3-9dc33ed8eef9");
long msb = id.getMostSignificantBits();
long lsb = id.getLeastSignificantBits();
System.out.println(msb + ", " + lsb);
// -1484283427208739237, -7281302710629372167
System.out.println(new UUID(msb, lsb));
// eb66c416-4739-465b-9af3-9dc33ed8eef9
This same example is referenced in another question which is pretty similar, so this would be a follow up. While in the related question problem of lsb, msb -> string was solved, I cannot find solution for reverse problem, string -> msb, lsb
The original solution was
function toUuidString(lsb, msb) {
return `${digits(msb >> 32n, 8n)}-${digits(msb >> 16n, 4n)}-${digits(
msb,
4n
)}-${digits(lsb >> 48n, 4n)}-${digits(lsb, 12n)}`
}
function digits(value, ds) {
const hi = 1n << (ds * 4n)
return (hi | (value & (hi - 1n))).toString(16).slice(1)
}
Now I'd like to have a function that takes in string and returns msb and lsb.
Following original questions' paths, I've discovered java source code and tried to do the equivalent, which would be:
function fromString(name) {
let components = name.split('-')
if (components.length !== 5) {
throw new Error(`Invalid UUID string: ${name}`)
}
for (let index = 0; index < 5; index++) {
components[index] = `0x${components[index]}`
}
let mostSigBits = Number.parseInt(components[0], 16)
mostSigBits <<= 16
mostSigBits |= Number.parseInt(components[1], 16)
mostSigBits <<= 16
mostSigBits |= Number.parseInt(components[2], 16)
let leastSigBits = Number.parseInt(components[3], 16)
leastSigBits <<= 48
leastSigBits |= Number.parseInt(components[4], 16)
return {
leastSigBits,
mostSigBits,
}
}
However, when I try to test this with something like:
const originalUuid = 'eb66c416-4739-465b-9af3-9dc33ed8eef9'
const parts = fromString(originalUuid)
const newUUid = toUuidString(
BigInt(parts.leastSigBits),
BigInt(parts.mostSigBits)
)
console.log('Original', originalUuid)
console.log('New', newUUid)
I do not get equivalent uuids. They have equivalent parts but some parts are missing
Original eb66c416-4739-465b-9af3-9dc33ed8eef9
New 00000000-4739-465b-ffff-ffffbefbeef9
Any ideas what went wrong?
Finally I found the problem - two codes were not strictly equivalent, java source code declared mostSigBits and leastSigBits as long, which cannot be represented in javascript, so we need to use BigInt.
To sum up my question and previous question, javascript equivalent for java's UUID operations would be:
string -> msb, lsb
function fromString(name) {
let components = name.split('-')
if (components.length !== 5) {
throw new Error(`Invalid UUID string: ${name}`)
}
for (let index = 0; index < 5; index++) {
components[index] = `0x${components[index]}`
}
let mostSigBits = BigInt(Number.parseInt(components[0], 16))
mostSigBits <<= 16n
mostSigBits |= BigInt(Number.parseInt(components[1], 16))
mostSigBits <<= 16n
mostSigBits |= BigInt(Number.parseInt(components[2], 16))
let leastSigBits = BigInt(Number.parseInt(components[3], 16))
leastSigBits <<= 48n
leastSigBits |= BigInt(Number.parseInt(components[4], 16))
return {
leastSigBits,
mostSigBits,
}
}
msb, lsb -> string (from the referenced question)
function toUuidString(lsb, msb) {
return `${digits(msb >> 32n, 8n)}-${digits(msb >> 16n, 4n)}-${digits(
msb,
4n
)}-${digits(lsb >> 48n, 4n)}-${digits(lsb, 12n)}`
}
function digits(value, ds) {
const hi = 1n << (ds * 4n)
return (hi | (value & (hi - 1n))).toString(16).slice(1)
}
i have equivalent c++ but not sure how to implement this in javascript/nodejs.
c++:
template <unsigned int BITS>
enum { WIDTH = BITS / 32 };
uint32_t pn[WIDTH];
uint256 seed = "00000800ab9d2c5409a9b4dea2aa6f8471cecc41b35706e6d6155098e5f3595d";
uint64_t Get64(int n = 0) const
{
return pn[2 * n] | (uint64_t)pn[2 * n + 1] << 32;
}
uint64_t first = seed.Get64(0) % 6 + 1;
uint64_t second = seed.Get64(1) % 6 + 1;
able to get uint64_t first with below. but not sure how to implement it for second one.
//uint64_t first = seed.Get64(0) % 6 + 1;
var bigInt = require("big-integer");
var hash = bigInt("00000800ab9d2c5409a9b4dea2aa6f8471cecc41b35706e6d6155098e5f3595d",16);
console.log(hash.and(new bigInt("ffffffffffffffff", 16)).mod(6) + 1)
//result of first = 6
How to do it with javascript "native" BigInt
const get64 = (value, n=0) => (value >> BigInt(64*n)) & 0xffffffffffffffffn;
const toNumber = value => +value.toString();
var hash = 0x00000800ab9d2c5409a9b4dea2aa6f8471cecc41b35706e6d6155098e5f3595dn;
var first = toNumber(get64(hash, 0) % 6n + 1n);
var second = toNumber(get64(hash, 1) % 6n + 1n);
console.log(first, second)
alternatively, you can do what many consider a big no-no and extend BigInt prototype - usually I'd suggest extending the BigInt class, but, that's not possible as far as I can tell (since new BigInt is not supported)
BigInt.prototype.get64 = function (n=0) {
return (this >> BigInt(64 * n)) & ((1n<<64n) - 1n);
}
BigInt.prototype.toNumber = function () {
return +this.toString();
}
var hash = 0x00000800ab9d2c5409a9b4dea2aa6f8471cecc41b35706e6d6155098e5f3595dn;
var first = (hash.get64(0) % 6n + 1n).toNumber();
var second = (hash.get64(1) % 6n + 1n).toNumber();
console.log(first, second)
I have an integer and i want to check if a single bit is 0 or 1.
What is the best practise for doing that?
An example of what i'm doing at this moment:
const myInt = 8; // Binary in 32 Bit integer = 00000000000000000000000000001000
const myBit = myInt << 28 >>> 31; // 00000000000000000000000000000001
if (myBit === 1) {
//do something
}
But i think that this isn't the best methode for doing this.
Have you any better idea?
EDIT:
It is always the same bit i want to check, but the integer is different
myInt = 8+4; // 1100
n = 3;
(myInt >> n) & 0x1; // 1
n = 2;
(myInt >> n) & 0x1; // 1
n = 1;
(myInt >> n) & 0x1; // 0
n = 0;
(myInt >> n) & 0x1; // 0
general solution shifts your number by N bits to right, and applies bitmask, that leaves only last bit, all other are set to 0
I think you can use the bitwise AND
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
my32Bit = 123414123;
twoBy7 = 128;
//check the 7th bit
if (my32Bit & twoBy7) {
// should return 1 if the 7thbit is 1
}
You could take the bit and a left shift << with bitwise AND & operator.
var value = 10,
bit;
for (bit = 0; bit < 4; bit++) {
console.log(bit, !!(value & (1 << bit)));
}
I am trying to write an algorithm for this in JavaScript but I am getting a str.length is not a function...
function extractMiddle(str) {
var position;
var length;
if(str.length() % 2 == 1) {
position = str.length() / 2;
length = 1;
} else {
position = str.length() / 2 - 1;
length = 2;
}
result = str.substring(position, position + length)
}
extractMiddle("handbananna");
Because string length is not a function, it's a property.
function extractMiddle(str) {
var position;
var length;
if(str.length % 2 == 1) {
position = str.length / 2;
length = 1;
} else {
position = str.length / 2 - 1;
length = 2;
}
return str.substring(position, position + length)
}
console.log(extractMiddle("handbananna"));
Here is an another way to do this:
function extractMiddle(str) {
return str.substr(Math.ceil(str.length / 2 - 1), str.length % 2 === 0 ? 2 : 1);
}
// the most amazing
const getMiddle = s => s.substr(s.length - 1 >>> 1, (~s.length & 1) + 1);
// should return "dd"
console.log(getMiddle('middle'))
// >>> is an unsigned right shift bitwise operator. It's equivalent to division by 2, with truncation, as long as the length of the string does not exceed the size of an integer in Javascript.
// About the ~ operator, let's rather start with the expression n & 1. This will tell you whether an integer n is odd (it's similar to a logical and, but comparing all of the bits of two numbers). The expression returns 1 if an integer is odd. It returns 0 if an integer is even.
// If n & 1 is even, the expression returns 0.
// If n & 1 is odd, the expression returns 1.
// ~n & 1 inverts those two results, providing 0 if the length of the string is odd, and 1 if the length of the sting is even. The ~ operator inverts all of the bits in an integer, so 0 would become -1, 1 would become -2, and so on (the leading bit is always the sign).
// Then you add one, and you get 0+1 (1) characters if the length of the string is odd, or 1+1 (2) characters if the length of the string is even.
#author by jacobb
the link of the source is: https://codepen.io/jacobwarduk/pen/yJpAmK
That seemed to fix it!
function extractMiddle(str) {
var position;
var length;
if(str.length % 2 == 1) {
position = str.length / 2;
length = 1;
} else {
position = str.length / 2 - 1;
length = 2;
}
result = str.substring(position, position + length)
console.log(result);
}
https://jsfiddle.net/sd4z711y/
The first 'if' statement is to get the odd number while the 'else if' is to get the even number.
function getMiddle(s)
{
if (s.length % 2 == 1) {
return s.substring((s.length / 2)+1, (s.length / 2))
} else if (s.length % 2 == 0) {
return s.substring((s.length / 2)-1, (s.length / 2)+1)
}
}
console.log(getMiddle("handers"));
console.log(getMiddle("test"));
Here is my solution :-
function pri(word) {
if (!word) return 'word should have atleast one character';
let w = [...word].reduce((acc, val) => (val == ' ' ? acc : (acc += val)));
let res = '';
let length = word.length;
let avg = length / 2;
let temp = avg % 2;
if (temp == 0) {
res += word.charAt(avg - 1) + word.charAt(avg);
} else {
res += word.charAt(avg);
}
return res;
}
console.log(pri("Lime")); // even letter
console.log(pri("Apple")); // odd letter
console.log(pri("Apple is Fruit")); // String sequence with space
console.log(pri("")); // empty string
here is my solution
function getMiddle(s){
let middle = Math.floor(s.length/2);
return s.length % 2 === 0
? s.slice(middle-1, middle+1)
: s.slice(middle, middle+1);
}
function extractMiddle(s) {
return s.substr(Math.ceil(s.length / 2 - 1), s.length % 2 === 0 ? 2 : 1);
}
extractMiddle("handbananna");
str.length is a property. Just get rid of the parentheses. Example:
if (str.length == 44) {
length is a property of string, not a function. Do this instead:
str.length % 2 === 1
Also, use I suggest favoring === over ==
Since length is not a function, there is no need to use ().
function getMiddle(str) {
if(str.length % 2 === 0 ) {
return str.substr(str.length/2-1, 2);
} else {
return str.charAt(Math.floor(str.length/2));
}
}
console.log(getMiddle("middbkbcdle"));
I'm writing a chat-server in node.js, and I want to store connected users IP-addresses in a mysql database as (unsigned) integers.
I have written a javascript method to convert an ip-address as string to an integer. I get some strange results however.
Here is my code:
function ipToInt(ip) {
var parts = ip.split(".");
var res = 0;
res += parseInt(parts[0], 10) << 24;
res += parseInt(parts[1], 10) << 16;
res += parseInt(parts[2], 10) << 8;
res += parseInt(parts[3], 10);
return res;
}
When I run call the method as ipToInt("192.168.2.44"); the result I get is -1062731220.
It seems like an overflow has occurred, which is strange, because the expected output (3232236076) is inside the number range in javascript (2^52).
When I inspect -1062731220 in binary form, I can see the 3232236076 is preserved, but filled with leading 1's.
I'm not sure, but I think the problem is with signed vs. unsigned integers.
Can any of you explain what is going on?
And possibly how to parse -1062731220 back to an string ip?
Why is the converted IP negative?
It's NOT an overflow. The first part of your IP address is 192 which converts to 11000000 in binary. You then shift that all the way to the left. When there is a 1 in the leftmost position of a 32 bit number, it's negative.
How do you convert back to a string?
Do the same thing you did to convert from a string but in reverse. Shift right (and mask)!
function intToIP(int) {
var part1 = int & 255;
var part2 = ((int >> 8) & 255);
var part3 = ((int >> 16) & 255);
var part4 = ((int >> 24) & 255);
return part4 + "." + part3 + "." + part2 + "." + part1;
}
Why reinvent the wheel? From Google:
OR, you can use what I found here:
http://javascript.about.com/library/blipconvert.htm
function dot2num(dot)
{
var d = dot.split('.');
return ((((((+d[0])*256)+(+d[1]))*256)+(+d[2]))*256)+(+d[3]);
}
function num2dot(num)
{
var d = num%256;
for (var i = 3; i > 0; i--)
{
num = Math.floor(num/256);
d = num%256 + '.' + d;
}
return d;
}
The result of the "<<" operator is always a signed, 32-bit integer, as per the spec.
When you shift back, use ">>>" to do an unsigned right shift.
You might also find this pattern useful:
ip.toLong = function toInt(ip){
var ipl=0;
ip.split('.').forEach(function( octet ) {
ipl<<=8;
ipl+=parseInt(octet);
});
return(ipl >>>0);
};
ip.fromLong = function fromInt(ipl){
return ( (ipl>>>24) +'.' +
(ipl>>16 & 255) +'.' +
(ipl>>8 & 255) +'.' +
(ipl & 255) );
};
If you're using something like node.js where you can add functionality through something like Npm then you can simply do:
npm install ip
To get that functionality from the source which is here:
https://github.com/indutny/node-ip/blob/master/lib/ip.js
You will also get a bunch of other IP utility functions with that.
You shifted left to get the original number - which is just 4 sets of bits regardless of the sign.
Shift right to get back to the IP. Doesn't matter what the sign is.
const ip2int = (x) => (x.split('.').reduce((a, v) => ((a << 8) + (+v)), 0) >>> 0);
One-Liner:
const ipToLong = ip => ip.split('.').map(parseFloat).reduce((total, part) => total * 256 + part);
Use this
function num2string(ip) {
return [24,16,8,0].map(n => (ip >> n) & 0xff).join(".")
}
function string2num(ip) {
return ip.split(".").reduce((sum,x,i) => sum + (x << 8*(3-i)), 0)
}
IP Addresses in the V4 space are unsigned 32 bit numbers, hence the IP address of FF.FF.FF.FF is 2^32 and cannot be greater then that number. Please see:
This stack overflow article on the same subject
To turn that number back into an IP address you must break the number down into its 4 parts since each byte is one octet of the address so convert the number to hex and then parse out each pair. You may or may not have to add a leading zero for the first octet.
Additionally you may have to deal with byte order of the integer ( endien issues ) but since most systems are intel based these days you might not have to deal with that.
var aaa = Number("0b"+ "192.168.2.44".split(".").map(
function(dec){
return ("00000000" + Number(dec).toString(2)).slice(-8);
}).join(""));
aaa.toString(2).match(/.{1,8}/g).map(
function(bin){
return Number("0b"+bin);
}).join(".");
I revised Evan's final answer a bit, particularly dot2num. It functions the same but might be more readable and is marginally slower.
function ip2num(ip) {
var parts = ip.split('.');
var num = 0;
num += d[0] * Math.pow(2, 24);
num += d[1] * Math.pow(2, 16);
num += d[2] * Math.pow(2, 8);
num += d[3];
return num;
}
function num2ip(num) {
var ip = num % 256;
for (var i=3; i > 0; i--) {
num = Math.floor(num / 256);
ip = num % 256 + '.' + ip;
}
return ip;
}
Try this solution, it might help:
function IpToInteger(ipAddr)
{
var parts = ipAddr.split('.');
return (((parts[0] ? parts[0] << 24 : 0) |
(parts[1] ? parts[1] << 16 : 0) |
(parts[2] ? parts[2] << 8 : 0) |
(parts[3])) >>> 0);
}
function IpAddressToLong(ip){
return ip.split('.').map((octet, index, array) => {
return parseInt(octet) * Math.pow(256, (array.length - index - 1));
}).reduce((prev, curr) => {
return prev + curr;
});
}
Taken from repo
function ip2num(ip) {
var d = ip.split(".");
var num = 0;
num += Number(d[0]) * Math.pow(256, 3);
num += Number(d[1]) * Math.pow(256, 2);
num += Number(d[2]) * Math.pow(256, 1);
num += Number(d[3]);
return num;
}
function num2ip(num) {
var ip = num % 256;
for (var i = 3; i > 0; i--) {
num = Math.floor(num / 256);
ip = (num % 256) + "." + ip;
}
return ip;
}
console.log(ip2num("192.168.0.1"));
console.log(num2ip(3232235521))
<h1>YOU IS WELCOME</h1>