Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 216
ShaharZ Avatar asked Feb 12 '26 01:02

ShaharZ


2 Answers

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)

like image 169
zerkms Avatar answered Feb 14 '26 14:02

zerkms


<< 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

Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!