最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

node.js - JavaScript Bitwise Masking - Stack Overflow

programmeradmin0浏览0评论

This question is similar to this other question; however, I'd like to understand why this is working as it is.

The following code:

console.log((parseInt('0xdeadbeef', 16) & parseInt('0x000000ff', 16)).toString(16));
console.log((parseInt('0xdeadbeef', 16) & parseInt('0x0000ff00', 16)).toString(16));
console.log((parseInt('0xdeadbeef', 16) & parseInt('0x00ff0000', 16)).toString(16));
console.log((parseInt('0xdeadbeef', 16) & parseInt('0xff000000', 16)).toString(16));
console.log((parseInt('0xdeadbeef', 16) & parseInt('0x000000ff', 16)).toString(16));
console.log((parseInt('0xdeadbeef', 16) & parseInt('0x0000ffff', 16)).toString(16));
console.log((parseInt('0xdeadbeef', 16) & parseInt('0x00ffffff', 16)).toString(16));
console.log((parseInt('0xdeadbeef', 16) & parseInt('0xffffffff', 16)).toString(16));

Returns:

ef
be00
ad0000
-22000000
ef
beef
adbeef
-21524111

When what I am expecting from .string(16) would be:

ef
be00
ad0000
de000000
ef
beef
adbeef
deadbeef

What's going on with this?

Thank you in advance for your help.


With thank you to the responders and menters below, and also to the following sources:

  • .html
  • JavaScript C Style Type Cast From Signed To Unsigned

Here is a solution that works by providing utility functions to convert a radix-16 32-bit number to and from a signed 32-bit integer:

// Convert 'x' to a signed 32-bit integer treating 'x' as a radix-16 number
// c.f. .html
function toInt32Radix16(x) {
    return (parseInt(x, 16) | 0);
}

// Convert a signed 32-bit integer 'x' to a radix-16 number
// c.f. 
function toRadix16int32(x) {
    return ((x >>> 0).toString(16));
}

console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0x000000ff')));
console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0x0000ff00')));
console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0x00ff0000')));
console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0xff000000')));
console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0x000000ff')));
console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0x0000ffff')));
console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0x00ffffff')));
console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0xffffffff')));

Which yields the expected output:

ef
be00
ad0000
de000000
ef
beef
adbeef
deadbeef

As well as some good learning on my part about JavaScript integer behavior.

This question is similar to this other question; however, I'd like to understand why this is working as it is.

The following code:

console.log((parseInt('0xdeadbeef', 16) & parseInt('0x000000ff', 16)).toString(16));
console.log((parseInt('0xdeadbeef', 16) & parseInt('0x0000ff00', 16)).toString(16));
console.log((parseInt('0xdeadbeef', 16) & parseInt('0x00ff0000', 16)).toString(16));
console.log((parseInt('0xdeadbeef', 16) & parseInt('0xff000000', 16)).toString(16));
console.log((parseInt('0xdeadbeef', 16) & parseInt('0x000000ff', 16)).toString(16));
console.log((parseInt('0xdeadbeef', 16) & parseInt('0x0000ffff', 16)).toString(16));
console.log((parseInt('0xdeadbeef', 16) & parseInt('0x00ffffff', 16)).toString(16));
console.log((parseInt('0xdeadbeef', 16) & parseInt('0xffffffff', 16)).toString(16));

Returns:

ef
be00
ad0000
-22000000
ef
beef
adbeef
-21524111

When what I am expecting from .string(16) would be:

ef
be00
ad0000
de000000
ef
beef
adbeef
deadbeef

What's going on with this?

Thank you in advance for your help.


With thank you to the responders and menters below, and also to the following sources:

  • http://speakingjs./es5/ch11.html
  • JavaScript C Style Type Cast From Signed To Unsigned

Here is a solution that works by providing utility functions to convert a radix-16 32-bit number to and from a signed 32-bit integer:

// Convert 'x' to a signed 32-bit integer treating 'x' as a radix-16 number
// c.f. http://speakingjs./es5/ch11.html
function toInt32Radix16(x) {
    return (parseInt(x, 16) | 0);
}

// Convert a signed 32-bit integer 'x' to a radix-16 number
// c.f. https://stackoverflow./questions/14890994/javascript-c-style-type-cast-from-signed-to-unsigned
function toRadix16int32(x) {
    return ((x >>> 0).toString(16));
}

console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0x000000ff')));
console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0x0000ff00')));
console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0x00ff0000')));
console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0xff000000')));
console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0x000000ff')));
console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0x0000ffff')));
console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0x00ffffff')));
console.log(toRadix16int32(toInt32Radix16('0xdeadbeef') & toInt32Radix16('0xffffffff')));

Which yields the expected output:

ef
be00
ad0000
de000000
ef
beef
adbeef
deadbeef

As well as some good learning on my part about JavaScript integer behavior.

Share Improve this question edited May 23, 2017 at 11:56 CommunityBot 11 silver badge asked Feb 14, 2015 at 20:00 ptdeckerptdecker 4244 silver badges11 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

In JavaScript, all bitwise operations (and & among them) return signed 32-bit integer as a result, in the range −231 through 231−1, inclusive. That's why you have that extra bit (0xde000000 is greater than 0x7ffffff) representing a sign now, meaning that you get a negative value instead.

One possible fix:

var r = 0xdeadbeef & 0xff000000;
if (r < 0) {
  r += (1 << 30) * 4;
}
console.log( r.toString(16) ); // 'de000000'

Because bitwise operations (like &) are done on signed 32-bit integers in javascript. 0xFFFFFFFF, where all bits are set, is actually -1, and the 0xde000000 you are expecting is actually -570425344.

发布评论

评论列表(0)

  1. 暂无评论