3

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?

ShaharZ
  • 389
  • 5
  • 11
  • "I thought all bitwise operations in Javascript are on unsigned 32 bit floats" - signed 32-bit integers in two's complement https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators – jdphenix May 07 '15 at 00:03

2 Answers2

6

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)

zerkms
  • 249,484
  • 69
  • 436
  • 539
  • 1
    Re your PS, [Why doesn't C have unsigned floats](http://stackoverflow.com/questions/512022/why-doesnt-c-have-unsigned-floats). – Mike Samuel May 07 '15 at 00:12
  • Answer below works better. Just add >>>0 to the end of your line to make everything unsigned and fix the mess. – opcode Aug 06 '22 at 13:19
  • @opcode if you check comments to the other answer you may see that it's me suggested them to use `>>> 0` :-D – zerkms Aug 06 '22 at 22:41
5

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