intmath.c

来自「傅立叶变换和小波变换是图像压缩的重要工具。该代大戏是利用小波变换进行图像压缩。」· C语言 代码 · 共 418 行

C
418
字号
#include <crblib/inc.h>
#include <crblib/intmath.h>

#ifdef _MSC_VER
#pragma warning(disable : 4018) //signed/unsigned compare
#endif

	static unsigned char log2x16_table[256] = {	0,
	 0,16,25,32,37,41,45,48,51,53,55,57,59,61,63,64,
	65,67,68,69,70,71,72,73,74,75,76,77,78,79,79,80,
	81,81,82,83,83,84,85,85,86,86,87,87,88,88,89,89,
	90,90,91,91,92,92,93,93,93,94,94,95,95,95,96,96,
	96,97,97,97,98,98,98,99,99,99,100,100,100,101,101,101,
	101,102,102,102,103,103,103,103,104,104,104,104,105,105,105,105,
	106,106,106,106,107,107,107,107,107,108,108,108,108,109,109,109,
	109,109,110,110,110,110,110,111,111,111,111,111,111,112,112,112,
	112,112,113,113,113,113,113,113,114,114,114,114,114,114,115,115,
	115,115,115,115,116,116,116,116,116,116,116,117,117,117,117,117,
	117,117,118,118,118,118,118,118,118,119,119,119,119,119,119,119,
	119,120,120,120,120,120,120,120,121,121,121,121,121,121,121,121,
	121,122,122,122,122,122,122,122,122,123,123,123,123,123,123,123,
	123,123,124,124,124,124,124,124,124,124,124,125,125,125,125,125,
	125,125,125,125,125,126,126,126,126,126,126,126,126,126,126,127,
	127,127,127,127,127,127,127,127,127,127,128,128,128,128,128	};

#ifndef DO_ASM_LOG2S //{

uint ilog2round(uint val)
{
#ifdef _MSC_VER
	__asm
	{
		FILD val
		FSTP val
		mov eax,val
		add eax,0x257D86 // (2 - sqrt(2))*(1<<22)
		shr eax,23
		sub eax,127
	}
#else

uint L;
	for(L=1; (1ul<<L) <= val; L++) ;
	L --;
	assert( val >= (1UL<<L) );
	val <<= (16 - L);
	assert( val >= 65536 && val < 65536*2 );
	if ( val >= 92682 ) // sqrt(2) * 1<<16
		L ++;
return L;

#endif
}

uint ilog2ceil (uint val)
{
#ifdef _MSC_VER

	__asm
	{
		FILD val
		FSTP val
		mov eax,val
		add eax,0x7FFFFF // 1<<23 - 1
		shr eax,23
		sub eax,127
	}

#else

uint L;
	for(L=0; (1ul<<L) < val; L++) ;
	// (1<<L) >= val;
return L;

#endif
}

uint ilog2floor(uint val)
{
#ifdef _MSC_VER

	__asm
	{
		FILD val
		FSTP val
		mov eax,val
		shr eax,23
		sub eax,127
	}

#else

uint L;
	for(L=1; (1ul<<L) <= val; L++) ;
	// (1<<l) > val;
return (L - 1);

#endif
}

int flog2(float xf)
{
return ((*(int*)&xf) >> 23) - 127;
}

#endif //}

int flog2x16(float val)
{
int il,frac,lx16;

	if ( val <= 0.0f ) return 0;

	if ( val < 1.0f )
	{
		il = 0;
		while( val < 1.0f )
		{
			il --;
			val *= 2.0f;
		}
		
		frac = (uint)(val * 128.0f);
	}
	else
	{

		il = flog2(val);

		assert( val >= (1UL << il) );

		frac = (uint)(val * 128.0f);
		frac = frac >> il;
		
		// val = 2^(il) * (frac/128)
	}

	assert( frac >= 128 && frac < 256 );

	lx16 = il << 4;

	il = log2x16_table[ frac ] - 112;
	assert( il >= 0 && il <= 16 );

	lx16 += il;

return lx16;
}

uint ilog2x16(uint val)
{
uint il,frac,lx16;

	if ( val <= 1 ) return 0;

	il = ilog2floor(val);

	assert( val >= (1UL << il) );

	frac = (val << 7) >> il;

	// val = 2^(il) * (frac/128)

	assert( frac >= 128 && frac < 256 );

	lx16 = il << 4;

	il = log2x16_table[ frac ] - 112;
	assert( il >= 0 && il <= 16 );

	lx16 += il;

return lx16;
}

ulong square(ulong val)
{
return ( val >= 0xFFFF ) ? ULONG_MAX : val*val;
}

static int bits[256] =
{
  0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
};

int intlog2_noif(register uword N) /** truncated **/
{
	static int throw_small[64] = {
	 0, 1, 2, 3, 4, 5, 6, 7, 9, 9, 9, 9, 9, 9, 9, 9,
	10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,
	12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,
	14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15
	};

	return throw_small[ (bits[ N>>8 ]<<3) + bits[ N & 0xFF ] ];
}

int intlog2_uw(register uword N) /** truncated **/
{
	if ( N >> 8 ) {
		return (8 + bits[N >> 8]);
	} else {
		return bits[N];
	}
}

int intlog2(ulong N) /** truncated **/
{
	if ( N >> 16 ) {
		if ( N >> 24 ) {
			return (24 + bits[N >> 24]);
		} else {
			return (16 + bits[N >> 16]);
		}
	} else {
		if ( N >> 8 ) {
			return (8 + bits[N >> 8]);
		} else {
			return bits[N];
		}
	}
}

int intlog2x10(ulong N) /** rounded **/
{
	static unsigned char log2x10_table[256] = {    0, 0,
		   10,16,20,23,26,28,30,32,33,35,36,37,38,39,40,
		41,42,42,43,44,45,45,46,46,47,48,48,49,49,50,50,
		50,51,51,52,52,52,53,53,54,54,54,55,55,55,56,56,
		56,56,57,57,57,58,58,58,58,59,59,59,59,60,60,60,
		60,60,61,61,61,61,61,62,62,62,62,62,63,63,63,63,
		63,64,64,64,64,64,64,65,65,65,65,65,65,66,66,66,
		66,66,66,66,67,67,67,67,67,67,67,68,68,68,68,68,
		68,68,68,69,69,69,69,69,69,69,69,70,70,70,70,70,
		70,70,70,70,71,71,71,71,71,71,71,71,71,71,72,72,
		72,72,72,72,72,72,72,72,73,73,73,73,73,73,73,73,
		73,73,73,74,74,74,74,74,74,74,74,74,74,74,75,75,
		75,75,75,75,75,75,75,75,75,75,75,76,76,76,76,76,
		76,76,76,76,76,76,76,76,77,77,77,77,77,77,77,77,
		77,77,77,77,77,77,77,78,78,78,78,78,78,78,78,78,
		78,78,78,78,78,78,79,79,79,79,79,79,79,79,79,79,
		79,79,79,79,79,79,79,80,80,80,80,80,80,80,80	};

	if ( N < 256 ) {
		return log2x10_table[N];
	} else {
		int b;
		b = 9;
		while( N > ((ulong)1<<b) ) b++;
		return b*10 - 80 + log2x10_table[ N>>(b-8) ];
	}
}

int intlog2x16(ulong N) /** rounded **/
{
	if ( N < 256 ) {
		return log2x16_table[N];
	} else {
		int b;
		b = 9;
		while( N > ((ulong)1<<b) ) b++;
		return ((b - 8)<<4) + log2x16_table[ N>>(b-8) ];
	}
}

int intlog2r(ulong N) /** rounded **/
{
 static unsigned char rbits[256] = {
	0,0,1,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,
	5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
	6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
	6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
	7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
	7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
	7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
	7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
	8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
	8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
	8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
	8,8,8,8,8
  };

	if ( N >> 16 ) {
		if ( N >> 24 ) {
			return (24 + rbits[N >> 24]);
		} else {
			return (16 + rbits[N >> 16]);
		}
	} else {
		if ( N >> 8 ) {
			return (8 + rbits[N >> 8]);
		} else {
			return rbits[N];
		}
	}
}

ulong isqrt(ulong N)
{
static const ubyte sqrtable[] = {
0, 1,1, 2,2,2,2, 3,3,3,3,3,3, 4,4,4,4,4,4,4,4,4,
5,5,5,5,5,5,5,5,5,5, 6,6,6,6,6,6,6,6,6,6,6,6,
7,7,7,7,7,7,7,7,7,7,7,7,7,7, 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,
11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
16,16,16,16,16,16,16,16,16,16,16,16 };

	/** get a quick estimate **/

	if ( N >= 256 )
	{
		long diff;
		ulong step,s;

		if ( N >> 16 ) {
			if ( N >> 24 )	s = sqrtable[N >>24]<<12;
			else 			s = sqrtable[N >>16]<<8;
		} else {
			s = sqrtable[N >> 8]<<4;
		}

	diff = N - s*s;

	if ( ABS(diff) < 2*s ) return s;

	step = isqrt(ABS(diff));

	for(;;) {
		step >>= 1; if ( step == 0 ) break;

		if ( diff > 0 ) s += step;
		else if ( diff < 0 ) s -= step;
		else break;

		diff = N - (s*s);
		if ( ABS(diff) < 2*s ) return s;
	}

	if ( (N - (s-1)*(s-1)) < ABS(diff) ) s--;
	else if ( (N - (s+1)*(s+1)) < ABS(diff) ) s++;

	return s;
  }

return sqrtable[N];
}


int GaussianRand(int val,int step)
{
int r;

	r = 0;

restart:

	r >>= 1;	if ( ! r ) r = rand() >> 1;
	if ( r&1 ) step = - step;

	step /= 2;
	if ( step == 0 ) return val;

	for(;;)
	{
		r >>= 1;	if ( ! r ) r = rand() >> 1;
		if ( r & 1 )
			val += step;
		else
		{
			//	return val + (rand()*step)/RAND_MAX;
			// step /= 2;
			val += (rand()*step)/RAND_MAX;
			goto restart;
		}
	}
}

static uint lastFastRand = 0xA2A9; // a prime

void fastRand_Seed(uint s)
{
	lastFastRand = 0xA2A9;
	s &= 0xFFFF;
	while(s--)
	{
		lastFastRand = lastFastRand * 65539 + 3;
		lastFastRand = lastFastRand * 1009  + 7;
	}
}

uint fastRand(uint max)
{
uint a;
	lastFastRand = lastFastRand * 65539 + 3;
	a = lastFastRand >> 16;
return a % max;
}

ubyte fastRandByte(void)
{
	lastFastRand = lastFastRand * 65539 + 3;
return (ubyte)(lastFastRand >> 24);
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?