For this you need to use a fixed point precision / arithmetic / math. This means that you use integer type variables, but some of the bits are after the decimal point.
for example, suppose 8 decimal bits, so the operations are performed as follows:
a = number1*256
b = number2*256
c=a+b // +
c=a-b // -
c=(a*b)>>8 // *
c=(a/b)<<8 // /
Here's an example of a simple fixed point log2via binary search in C ++ :
const DWORD _fx32_bits =32;
const DWORD _fx32_fract_bits= 8;
const DWORD _fx32_integ_bits=_fx32_bits-_fx32_fract_bits;
const DWORD _fx32_one =1<<_fx32_fract_bits;
const DWORD _fx32_fract_mask=_fx32_one-1;
const DWORD _fx32_integ_mask=0xFFFFFFFF-_fx32_fract_mask;
const DWORD _fx32_MSB_mask=1<<(_fx32_bits-1);
DWORD bits(DWORD p)
{
DWORD m=0x80000000; DWORD b=32;
for (;m;m>>=1,b--)
if (p>=m) break;
return b;
}
DWORD fx32_mul(DWORD x,DWORD y)
{
DWORD a=x,b=y;
asm {
mov eax,a
mov ebx,b
mul eax,ebx
mov ebx,_fx32_one
div ebx
mov a,eax;
}
return a;
return (x*y)>>_fx32_fract_bits;
}
DWORD fx32_sqrt(const DWORD &x)
{
DWORD m,a;
if (!x) return 0;
m=bits(x);
if (m>_fx32_fract_bits) m-=_fx32_fract_bits; else m=0;
m>>=1;
m=_fx32_one<<m;
for (a=0;m;m>>=1)
{
a|=m;
if (fx32_mul(a,a)>x)
a^=m;
}
return a;
}
DWORD fx32_exp2(DWORD y)
{
if (!y) return _fx32_one;
if (y==_fx32_one) return 2;
DWORD m,a,b,_y;
_y=y&_fx32_fract_mask;
y=y&_fx32_integ_mask;
a=_fx32_one;
if (y)
{
for (m=_fx32_MSB_mask;(m>_fx32_one)&&(m>y);m>>=1);
for (;m>=_fx32_one;m>>=1)
{
a=fx32_mul(a,a);
if (DWORD(y&m)) a<<=1;
}
}
if (_y)
{
for (b=2<<_fx32_fract_bits,m=_fx32_one>>1;m;m>>=1)
{
b=fx32_sqrt(b);
if (DWORD(_y&m)) a=fx32_mul(a,b);
}
}
return a;
}
DWORD fx32_log2(DWORD x)
{
DWORD y,m;
for (y=0,m=_fx32_one<<(bits(_fx32_integ_bits)-1);m;m>>=1)
{
y|=m;
if (fx32_exp2(y)>x) y^=m;
}
return y;
}
( , , ):
float(fx32_log2(float(125.67*float(_fx32_one)))) / float(_fx32_one)
: log2(125.67) = 6.98828125 6.97349648, . , . :
(100*fx32_log2(125.67*_fx32_one))>>_fx32_fract_bits
698, 6.98 100. , .
, _fx32_fract_bits. , ++ DWORD, 32bit unsigned int. (, 16 64), .
:
[Edit2] fx32_mul 32- asm base 2^16 O(n^2)
DWORD fx32_mul(DWORD x,DWORD y)
{
const int _h=1;
const int _l=0;
union _u
{
DWORD u32;
WORD u16[2];
}u;
DWORD al,ah,bl,bh;
DWORD c0,c1,c2,c3;
u.u32=x; al=u.u16[_l]; ah=u.u16[_h];
u.u32=y; bl=u.u16[_l]; bh=u.u16[_h];
c0=(al*bl);
c1=(al*bh)+(ah*bl);
c2=(ah*bh);
c3= 0;
c3+=c2>>16; c2&=0x0000FFFF;
c2+=c1>>16; c1&=0x0000FFFF;
c1+=c0>>16; c0&=0x0000FFFF;
c2+=c1>>16; c1&=0x0000FFFF;
c3+=c2>>16; c2&=0x0000FFFF;
u.u16[_l]=c0; u.u16[_h]=c1; c0=u.u32;
u.u16[_l]=c2; u.u16[_h]=c3; c1=u.u32;
c0 =(c0&_fx32_integ_mask)>>_fx32_fract_bits;
c0|=(c1&_fx32_fract_mask)<<_fx32_integ_bits;
return c0;
}
WORD,DWORD,
typedef unsigned __int32 DWORD;
typedef unsigned __int16 WORD;
:
typedef uint32_t DWORD;
typedef uint16_t WORD;
[Edit3] fx32_mul
/ (15 ):
fx32_mul(0x00123400,0x00230056);
:
0x00123400/32768 * 0x00230056/32768 =
36 * 70.00262451171875 = 2520.094482421875
:
DWORD fx32_mul(DWORD x,DWORD y)
{
const int _h=1;
const int _l=0;
union _u
{
DWORD u32;
WORD u16[2];
}u;
DWORD al,ah,bl,bh;
DWORD c0,c1,c2,c3;
u.u32=x; al=u.u16[_l]; ah=u.u16[_h];
u.u32=y; bl=u.u16[_l]; bh=u.u16[_h];
c0=(al*bl);
c1=(al*bh)+(ah*bl);
c2=(ah*bh);
c3= 0;
c3+=c2>>16; c2&=0x0000FFFF;
c2+=c1>>16; c1&=0x0000FFFF;
c1+=c0>>16; c0&=0x0000FFFF;
c2+=c1>>16; c1&=0x0000FFFF;
c3+=c2>>16; c2&=0x0000FFFF;
u.u16[_l]=c0; u.u16[_h]=c1; c0=u.u32;
u.u16[_l]=c2; u.u16[_h]=c3; c1=u.u32;
c0 =(c0&_fx32_integ_mask)>>_fx32_fract_bits;
c0|=(c1&_fx32_fract_mask)<<_fx32_integ_bits;
return c0;
}