THIS SECTION IS UNDER CONSTRUCTION
Специальные функции очень важны, часто их реализуют аппаратно в микропроцессорах и используя их можно довольно хорошо оптимизировать вычисления. В этой секции расказывается как их проэмулировать если они недоступны (например не реализованны аппаратно, или ваш язык программирования не поддерживает такие операции).
Арифметический сдвиг вправо Shift Arithmetic Right
для 32-битной машины в дополнительном коде:
X >>> N = ((X + 0x80000000) >> N) - (0x80000000 >> N) |
unsigned long genshift(unsigned long v, int x) { int a,b; a = (v << x) & -(((unsigned int) x) < 32); x = -x; b = (v >> x) & -(((unsigned int) x) < 32); return a | b; } |
ABS(X) = | X, X >= 0 | -X, X < 0 |
NABS - нетативная абсолютная величина числа
NABS(X) = | X, X <= 0 | -X, X > 0 |
для 32-битной машины в дополнительном коде: пусть Y = X >>> 31, тогда ABS(X) = (X ^ Y) - Y = (X + Y) ^ Y = X - (2X & Y) NABS(X) = Y - (X ^ Y) = (Y - X) ^ Y = (2X & Y) - X
Rotate Right:
int ntz(unsigned x) { unsigned y, bz, b4, b3, b2, b1, b0; y = x & -x; // Isolate rightmost 1-bit. bz = y ? 0 : 1; // 1 if y = 0. b4 = (y & 0x0000FFFF) ? 0 : 16; b3 = (y & 0x00FF00FF) ? 0 : 8; b2 = (y & 0x0F0F0F0F) ? 0 : 4; b1 = (y & 0x33333333) ? 0 : 2; b0 = (y & 0x55555555) ? 0 : 1; return bz + b4 + b3 + b2 + b1 + b0; } |
int ntz(unsigned x) { static char table[32] = { 0, 1, 2,24, 3,19, 6,25, 22, 4,20,10,16, 7,12,26, 31,23,18, 5,21, 9,15,11, 30,17, 8,14,29,13,28,27 }; if (x == 0) return 32; x = (x & -x) * 0x04D7651F; return table[x >> 27]; } |