0

I'm trying to get a handle on the interaction between different types of typed arrays.

Example 1.

var buf = new ArrayBuffer(2);
var arr8 = new Int8Array(buf);
var arr8u = new Uint8Array(buf);

arr8[0] = 7.2;
arr8[1] = -45.3;

console.log(arr8[0]);       // 7
console.log(arr8[1]);       // -45
console.log(arr8u[0]);      // 7
console.log(arr8u[1]);      // 211

I have no problem with the first three readouts but where does 211 come from in the last. Does this have something to do with bit-shifting because of the minus sign.

Example 2

var buf = new ArrayBuffer(4);
var arr8 = new Int8Array(buf);
var arr32 = new Int32Array(buf);

for (var i = 0; i < buf.byteLength; i++){
    arr8[i] = i;
}

console.log(arr8);      // [0, 1, 2, 3]
console.log(arr32);     // [50462976]

So where does the 50462976 come from?

2 Answers 2

4

Example #1

Examine positive 45 as a binary number:

> (45).toString(2)
"101101"

Binary values are negated using a two's complement:

00101101 => 45 signed 8-bit value
11010011 => -45 signed 8-bit value

When we read we read 11010011 as an unsigned 8-bit value, it comes out to 211:

> parseInt("11010011", 2);
211

Example #2

If you print 50462976 in base 2:

> (50462976).toString(2);
"11000000100000000100000000"

We can add leading zeros and rewrite this as:

00000011000000100000000100000000

And we can break it into octets:

00000011 00000010 00000001 00000000

This shows binary 3, 2, 1, and 0. The storage of 32-bit integers is big-endian. The 8-bit values 0 to 3 are read in order of increasing significance when constructing the 32-bit value.

Sign up to request clarification or add additional context in comments.

1 Comment

@apsillers...this helped me too
2

First question.

Signed 8bit integers range from -128 to 127. The positive part (0-127) maps to binary values from 00000000 to 01111111), and the other half (-128-1) from 10000000 to 11111111.

If you omit the first bit, you can create a number by adding a 7bit number to a boundary. In your case, the binary representation is 11010011. The first bit is 1, this means the number will be negative. The last 7bits are 1010011, that gives us value 83. Add it to the boundary: -128 + 83 = -45. That’s it.

Second question.

32bit integers are represented by four bytes in memory. You are storing four 8bit integers in the buffer. When converted to an Int32Array, all those values are combined to form one value.

If this was decimal system, you could think of it as combining "1" and "2" gives "12". It’s similar in this case, except the multipliers are different. For the first value, it’s 2^24. Then it’s 2^16, then 2^8 and finally 2^0. Let’s do the math:

2^24 * 3 + 2^16 * 2 + 2^8 * 1 + 2^0 * 0 =
16777216 * 3 + 65536 * 2 + 256 * 1 + 1 * 0 =
50331648 + 131072 + 256 + 0 =
50462976

That’s why you’re seeing such a large number.

1 Comment

Thanks guys. Good explanations. I think I'll check out basic binary. Seems more to this than just 1 and 0. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.