How to match a long integer with an N-dimensional vector of smaller integers (and a fast inverse)?

For an N-dimensional vector of small integers, is there any simple way to compare it with a one-to-one correspondence with a large integer?

Say we have an N = 3 vector space. Is it possible to imagine the vector X = [(int16) x1, (int16) x2, (int16) x3] using the integer (int48) y? The obvious answer is "Yes, we can." But the question arises: "What is the fastest way to do this and its inverse operation?"

Will this new one-dimensional space have some very useful properties?

+3
source share
8 answers

, 8- , :

uint8_t vector[3] = { 1, 2, 3 };

(24- ), :

uint32_t all = (vector[0] << 16) | (vector[1] << 8) | vector[2];

:

printf("the vector was packed into %06x", (unsigned int) all);

the vector was packed into 010203

:

uint8_t v2[3];

v2[0] = (all >> 16) & 0xff;
v2[1] = (all >> 8) & 0xff;
v2[2] = all & 0xff;

, , , "" .

+2

3 * 32 = 96 , - 96 .

, , x1, x2, x3 , , 16 , 48- .

, shift, mask bitwise or / .

+7

Si, i=1..n Ci = |Si|, {t23 > C = C1 * C2 * ... * Cn.

" ". e1,...,en , 0 Ci-1, e=(e1,...,en) e1+C1*(e2 + C2*(e3 + C3*(...Cn*en...))).

, , , .

32- , , 96- .

, (, L1), , .

(, (n,m) (max(n,m)-1)^2 + k, k=n, n<=m k=n+m, n>m - :

1 2 5   | draw along the edge of the square this way
4 3 6   v
  8 7

1 ; , .)

+2

, , , - , k , . , . , , , .

+1

Rex Kerr's, C :

X = e[n];

X *= MAX_E[n-1] + 1;
X += e[n-1];

/* ... */

X *= MAX_E[0] + 1;
X += e[0];

:

e[0] = X % (MAX_E[0] + 1);
X /= (MAX_E[0] + 1);

e[1] = X % (MAX_E[1] + 1);
X /= (MAX_E[1] + 1);

/* ... */

e[n] = X;

( MAX_E[n] - , e[n]). , , , e, .

/, , , , MAX_E + 1 2 (, , , - ).

+1

, . , , . . , , GPU, ().

- , , , (, , ) , , t .

, ( sub), .

0

, , . , , , . . N.

, .

, , , "16- int 32-" 48- int " .

0
#include <stdint.h> // for uint8_t
long x;
uint8_t * p = &x;

union X {
   long L;
   uint8_t A[sizeof(long)/sizeof(uint8_t)];
};

works if you don't care about endian. In my experience, compilers generate more efficient code with concatenation because it doesn’t set them "you selected the address of this, so I have to keep it in RAM" just as quickly. These rules will be canceled if you try to index the array so that the compiler cannot optimize.

If you care about endian, you need to mask and move.

0
source

Source: https://habr.com/ru/post/1746370/


All Articles