简体   繁体   中英

Javascript bit shift to 32 bits

I have an array of ints

var ints = [R,B,G,A]

and I want to use shifting to get a 32-bit representation

var thirtyTwo = AGBR

so for example,

[255.0, 0.0, 0.0, 255.0] => 0xFF0000FF => 4278190335

I'm attempting to do this with a loop and bitshift:

function cArrayToABGR(va) {
    var res = 0;
    for (var i = 0; i < va.length; ++i) {
        var color = va[i];
        color <<= (8 * i);
        res += color;
    }
    return res;
}

But the main problem is when I bitshift 255.0 << 24, I get a negative number

255.0 << 24 = -16777216    

which tells me I either hit a bit limit or the res is signed. I thought all bitwise operations in Javascript are on unsigned 32 bit floats, so not sure what's going on here. Help?

In JS all bitwise operators are signed 32bit, whereas your result is unsigned 32bit.

As a workaround you could calculate it as:

var res = ints.reduce(function(result, current) {
    return result * 256 + current;
}, 0); // 4278190335

which is even nicer in ES2015:

var res = ints.reduce((result, current) => result * 256 + current, 0);

PS: not sure if a thing like "unsigned float" even exists somewhere (at least for the languages that implement IEEE754)

<< works on signed 32-bit integers, while >>> is unsigned , so you can use >>> 0 to get an unsigned integer:

(255 << 24) >>> 0 // 4278190080

So:

var ints = [255.0, 0.0, 0.0, 255.0];

function cArrayToABGR(va) {
    var res = 0;
    for (var i = 0; i < va.length; ++i) {
        var color = va[i];
        color <<= (8 * i);
        res += color;
    }
    return res >>> 0;
}

console.log(cArrayToABGR(ints));
// 4278190335

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM