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];
}
|