⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jmaths.pas

📁 定点数函数集
💻 PAS
📖 第 1 页 / 共 3 页
字号:

function MapFXY(fxy: FIXED): Longint;  // = Fixed2Int
var
lxy : double;
begin
 lxy := Longint(fxy);
	result := Round(lxy / 65536.0);
end;

function IntFromFixed(f: FIXED): Longint; // = Fixed2Int
begin
 if f.fract >= $8000 then result := f.value + 1
                     else result := f.value;
end;

{ *********************** Fixed-point Number function *************************}

function int2Fix(x: Longint): FIXED; assembler; register;
asm
 sal eax,16;
end;

function Fix2int(x: FIXED): Longint; assembler; register;
asm
 sar eax,16
end;

function FixAdd(a,b: FIXED): FIXED; assembler; register;
asm
 add eax,edx
end;

function FixSub(a,b: FIXED): FIXED; assembler; register;
asm
 sub eax,edx
end;

function FixRound(x: Fixed): Longint; assembler; register;
asm
 add  eax,$00007FFF
 shr  eax,16
end;

function FixMul(x,y : FIXED): FIXED; assembler; register;
asm
 mov  ecx,edx
 imul ecx
 shr  eax,16
 sal  edx,16
 or   eax,edx
end;

function FixDiv(x, y: Fixed): Fixed; assembler; register;
asm
 mov  ecx,edx
 mov  edx,eax
 shl  eax,16
 sar  edx,16
 idiv ecx
end;

function FixAverageA(x, y: Fixed): Fixed; assembler; register;
asm
 mov  ecx,2
 add  eax,edx
 cdq
 idiv  ecx
end;

function FixAverageB(x,y: FIXED): FIXED;
var
l : Longint;
begin
 l := (Longint(x) + Longint(y)) div 2;
 result := FIXED(l);
end;

function Float2Fix(x: double): FIXED;
begin
	result := FIXED(Longint(Trunc(x * 65536)));
end;

function Fix2Float(Value: FIXED): double;
begin
 result := Longint(Value) * (1.0 / 65536);
end;

// ************* fp.java 16:16 Fixed-Point number Math Library v1.3 ************

function JFixToInt(x: Longint): Longint;
begin
	result := x shr 16;
end;

function JIntToFix(x : Longint): Longint;
begin
	result := x shl 16;
end;

function JFixMul(x,y : Longint): Longint;
var
z : Int64;
begin
	z := Int64(x) * Int64(y);
	result := z shr 16;
end;

function JFixDiv(x,y : Longint): Longint;
var
z : Int64;
begin
	z := Int64(x) shl 32;
	result := Round(z / Int64(y)) shr 16;
end;

function JFixSqrt(n : Longint): Longint;
var
i : Longint;
s : Longint;
begin
	s := (n + 65536) shr 1;
	for i := 0 to 7 do begin
  //converge six times
  s := (s + JFixDiv(n,s)) shr 1;
	end;
	result := s;
end;

function JFixRound(n : Longint): Longint;
var
k : Longint;
begin
	if n > 0 then begin
	 if (n and $8000) <> 0  then begin
 		result := (((n + $10000) shr 16) shl 16);
   exit;
	 end else begin
	 	result := ((n shr 16) shl 16);
   exit;
	 end;
	end else begin
	 n := -n;
	 if (n and $8000) <> 0 then k := (((n + $10000) shr 16) shl 16)
	                       else k := ((n shr 16) shl 16);
  result := -k;
	end;
end;

const
JCPI : Longint = 205887;
JCPI_OVER_2 : Longint = 102943; // JCPI / 2
JCE : Longint = 178145;
JCHALF : Longint = 2 shl 15;
// For the inverse tangent calls, all approximations are valid for |t| <= 1.
// To compute ATAN(t) for t > 1, use ATAN(t) = PI/2 - ATAN(1/t).  For t < -1,
// use ATAN(t) = -PI/2 - ATAN(1/t).
JCSK1 : Longint = 498;
JCSK2 : Longint = 10882;
// Computes SIN(f), f is a fixed point number in radians.
// 0 <= f <= 2PI
// If in range -pi/4 to pi/4: nothing needs to be done.
// otherwise, we need to get f into that range and account for
// sign change.

function JFixSin(f: Longint): Longint;
var
vsign : Longint;
vsqr : Longint;
begin
 vsign := 1;
	if (f > JCPI_OVER_2) and (f <= JCPI) then f := JCPI - f else
 if (f > JCPI) and (f <= (JCPI + JCPI_OVER_2)) then begin
  f := f - JCPI;
  vsign := -1;
	end else
 if f > (JCPI + JCPI_OVER_2) then begin
  f := (JCPI shl 1) - f;
  vsign := -1;
 end;
	vsqr := JFixMul(f,f);
	result := JCSK1;
	result := JFixMul(result,vsqr);
	dec(result,JCSK2);
	result := JFixMul(result,vsqr);
	inc(result,1 shl 16);
	result := JFixMul(result,f);
	result := vsign * result;
end;

const
JCCK1 : Longint = 2328;
JCCK2 : Longint = 32551;

function JFixCos(f: Longint): Longint;
var
vsign : Longint;
vsqr : Longint;
begin
	vsign := 1;
	if (f > JCPI_OVER_2) and (f <= JCPI) then begin
  f := JCPI - f;
  vsign := -1;
	end else
 if (f > JCPI_OVER_2) and (f <= (JCPI + JCPI_OVER_2)) then begin
	 f := f - JCPI;
	 vsign := -1;
	end else
 if f > (JCPI + JCPI_OVER_2) then f := (JCPI shl 1) - f;
	vsqr := JFixMul(f,f);
	result := JCCK1;
	result := JFixMul(result,vsqr);
	dec(result,JCCK2);
	result := JFixMul(result,vsqr);
	inc(result,1 shl 16);
	result := result * vsign;
end;

const
JCTK1 : Longint = 13323;
JCTK2 : Longint = 20810;

function JFixTan(f : Longint): Longint;
var
vsqr : Longint;
begin
	vsqr := JFixMul(f,f);
	result := JCTK1;
	result := JFixMul(result,vsqr);
	inc(result,JCTK2);
	result := JFixMul(result,vsqr);
	inc(result,1 shl 16);
	result := JFixMul(result,f);
end;

function JFixArcTan(f : Longint): Longint;
var
vsqr : Longint;
begin
	vsqr := JFixMul(f,f);
	result := 1365;
	result := JFixMul(result,vsqr);
	dec(result,5579);
	result := JFixMul(result,vsqr);
	inc(result,11805);
	result := JFixMul(result,vsqr);
	dec(result,21646);
	result := JFixMul(result,vsqr);
	inc(result,65527);
	result := JFixMul(result,f);
end;

const
JCAS1 : Longint = -1228;
JCAS2 : Longint = 4866;
JCAS3 : Longint = 13901;
JCAS4 : Longint = 102939;

function JFixArcSin(f : Longint): Longint;
var
fRoot : Longint;
begin
	fRoot := JFixSqrt((1 shl 16) - f);
	result := JCAS1;
	result := JFixMul(result,f);
	inc(result,JCAS2);
	result := JFixMul(result,f);
	dec(result,JCAS3);
	result := JFixMul(result,f);
	inc(result,JCAS4);
	result := JCPI_OVER_2 - (JFixMul(fRoot,result));
end;

function JFixArcCos(f : Longint): Longint;
var
fRoot : Longint;
begin
	fRoot := JFixSqrt((1 shl 16) - f);
	result := JCAS1;
	result := JFixMul(result,f);
	inc(result,JCAS2);
	result := JFixMul(result,f);
	dec(result,JCAS3);
	result := JFixMul(result,f);
	inc(result,JCAS4);
	result := JFixMul(fRoot,result);
end;

const
JCfpfact : array[0..8] of Longint =
 (
  65536,
  65536,
  131072,
  393216,
  1572864,
  7864320,
  47185920,
  330301440,
  -1652555776
 );

function JFixExp(x : Longint): Longint;
var
x2 : Longint;
x3 : Longint;
x4 : Longint;
x5 : Longint;
x6 : Longint;
x7 : Longint;
x8 : Longint;
begin
	result := 1 shl 16;
	x2 := JFixMul(x,x);
	x3 := JFixMul(x2,x);
	x4 := JFixMul(x2,x2);
	x5 := JFixMul(x4,x);
	x6 := JFixMul(x4,x2);
	x7 := JFixMul(x6,x);
	x8 := JFixMul(x4,x4);
	result := result + x +
           JFixDiv(x2,JCfpfact[2]) +
           JFixDiv(x3,JCfpfact[3]) +
           JFixDiv(x4,JCfpfact[4]) +
           JFixDiv(x5,JCfpfact[5]) +
           JFixDiv(x6,JCfpfact[6]) +
           JFixDiv(x7,JCfpfact[7]) +
           JFixDiv(x8,JCfpfact[8]);
end;

const
JClog2arr : array[0..18] of Longint =
 (
  26573,
  14624,
  7719,
  3973,
  2017,
  1016,
  510,
  256,
  128,
  64,
  32,
  16,
  8,
  4,
  2,
  1,
  0,
  0,
  0
 );

JClnscale : array[0..16] of Longint =
 (
  0,
  45426,
  90852,
  136278,
  181704,
  227130,
  272557,
  317983,
  363409,
  408835,
  454261,
  499687,
  545113,
  590539,
  635965,
  681391,
  726817
 );

function JFixLn(x : Longint): Longint;
var
shift : Longint;
g : Longint;
d : Longint;
i : Longint;
begin
	// prescale so x is between 1 and 2
	shift := 0;

	while x > (1 shl 17) do begin
	 inc(shift);
  x := x shr 1;
	end;
	g := 0;
	d := JCHALF;
	for i := 1 to 15 do begin
	 if x > ((1 shl 16) + d) then begin
	 	x := JFixDiv(x,(1 shl 16) + d);
 		inc(g,JClog2arr[i - 1]); // log2arr[i-1] = log2(1 + d);
	 end;
  d  := d shr 1;
	end;
	result := g + JClnscale[shift];
end;

var
JVxIntersect : Longint;
JVyIntersect : Longint;

function JFixIntersects(ax0,ay0,ax1,ay1,bx0,by0,bx1,by1: Longint): boolean;
var
adx,ady,bdx,bdy : Longint;
xma,xba,xmb,xbb : Longint;
TWO,dist,xa,xb : Longint;
minxa,maxxa,minya,maxya : Longint;
minxb,maxxb,minyb,maxyb : Longint;
begin
	ax0 := ax0 shl 16;
	ay0 := ay0 shl 16;
	ax1 := ax1 shl 16;
	ay1 := ay1 shl 16;
	bx0 := bx0 shl 16;
	by0 := by0 shl 16;
	bx1 := bx1 shl 16;
	by1 := by1 shl 16;

⌨️ 快捷键说明

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