What is the difference between a Uint8array and a Uint8clampedarray?

Asked

Viewed 165 times

8

I was reading about Uint8Array and Uint8ClampedArray on MDN, more specifically on the Typedarrays and I came across a table that compares the different types.

inserir a descrição da imagem aqui

They’re basically the same, only one is "clamped" and so far I’ve only seen Uint8ClampedArray being used with canvas.

In the documentation it says:

The Uint8clampedarray typed array represents an array of 8-bit unsigned integers clamped to 0-255;

Only that any whole unsigned 8-bit will contain only numbers between 0 and 255.

So I’d like to ask, what’s the difference between Uint8Array and Uint8ClampedArray?

  • In the Uint8ClampedArrayif we specify values outside the range 0-255 they will be changed to 0 or 255. If we specify a non-integer value it will be changed to the nearest integer.

  • and in the Uint8array it is not so? What is the difference?

  • In the Uint8Array the value assigned is based on the first 8 bits of the specified value.

1 answer

7


TL;DR

The difference between both happens when we try to insert an integer value outside allowed range (0 and 255 inclusive).

Uint8ClampedArray

  • If it is a negative number, the value will be 0
  • If it is a number greater than 255, the value will be 255
let array = new Uint8ClampedArray([-1, 0, 255, 256]);
// resultado: Uint8ClampedArray([0, 0, 255, 255]);

Uint8Array

Always save the 8 least significant bits (the direct):

let array = new Uint8Array([-1, 0, 255, 256]);
// resultado: Uint8Array([255, 0, 255, 0]);

For:

┌─────────┬────────────────────────────────────┬─────────────────┐
│ Decimal │       Binário (8bits finais)       │      8bits      │
├─────────┼────────────────────────────────────┼─────────────────┤
│      -1 │ 111111111111111111111111(11111111) │ 11111111 == 255 │
│     256 │ 000000000000000000000001(00000000) │ 00000000 == 0   │
└─────────┴────────────────────────────────────┴─────────────────┘

Full answer

The difference between Uint8array and Uint8clampedarray is in assigning values to their respective items.

In the specification of Ecmascrpt 2015 shows that the conversion operation to Uint8Arrayand Uint8ClampedArray are different. Being they:

  • Touint8 (used in Uint8arrays):

    1. Let number be ToNumber(argument).
    2. ReturnIfAbrupt(number).
    3. If number is Nan, +0, 0, +∞, or , Return +0.
    4. Let int be the Mathematical value that is the same number and Whose magnitude is floor(abs(number)).
    5. Let int8bit be int modulo 28.
    6. Return int8bit.
  • Touint8clamp (used in Uint8clampedarrays):

    1. Let number be ToNumber(argument).
    2. ReturnIfAbrupt(number).
    3. If number is Nan, Return +0.
    4. If number 0, Return +0.
    5. If number 255, Return 255.
    6. Let f be floor(number).
    7. If f + 0.5 < number, Return f + 1.
    8. If number < f + 0.5, Return f.
    9. If f is Odd, Return f + 1.
    10. Return f.

What you two do is basically:

  • Convert the value to an 8-bit integer
  • Treat some special cases as NaN, Infinity, etc....

The main difference is in this conversion to integer where:

  • Uint8array: truncates the value to integer and uses only the last 8 bits of the number, ignoring the rest.

    Would be analogous to:

    let n = meuNumero
    n = n & 0xff
    

    Example:

    let array = new Uint8Array([
        0,    // 0x00000000
        255,  // 0x000000ff
        256,  // 0x00000100
        -1    // 0xffffffff
    ])
    
    // Usa apenas os 8 bits da direita (últimos 2 caracteres hexadecimais)
    console.log(array[0])  // 00
    console.log(array[1])  // ff
    console.log(array[2])  // 00
    console.log(array[3])  // ff

  • Uint8clampedarray: round the value using "round half to Even" (if the number is N.5 rounding is done for the nearest even number, ex: 2.5 → 2 and 1.5 → 2). If the rounded value is less than 0 the value will be 0, if the value is greater than 255 the value will be 255.

    Would be analogous to:

    let n = meuNumero
    n = Math.min(n, 255)
    n = Math.max(n, 0)
    

    Example:

    let array = new Uint8ClampedArray([0, 255, 256,-1])
    
    // Se o valor for menor que zero, o valor será 0
    // Se o valor for maior que 255, o valor será 255
    console.log(array[0])  // 0
    console.log(array[1])  // 255
    console.log(array[2])  // 255
    console.log(array[3])  // 0

Browser other questions tagged

You are not signed in. Login or sign up in order to post.