1,183
社区成员
发帖
与我相关
我的任务
分享
SinLUT: array [0..128] of Cardinal = ( // Degrees for full circle: 0 -- 512 clockwise
$00000000, $00C90E90, $0192155F, $025B0CAF, $0323ECBE, $03ECADCF, $04B54825, $057DB403,
$0645E9AF, $070DE172, $07D59396, $089CF867, $09640837, $0A2ABB59, $0AF10A22, $0BB6ECEF,
$0C7C5C1E, $0D415013, $0E05C135, $0EC9A7F3, $0F8CFCBE, $104FB80E, $1111D263, $11D3443F,
$1294062F, $135410C3, $14135C94, $14D1E242, $158F9A76, $164C7DDD, $17088531, $17C3A931,
$187DE2A7, $19372A64, $19EF7944, $1AA6C82B, $1B5D100A, $1C1249D8, $1CC66E99, $1D79775C,
$1E2B5D38, $1EDC1953, $1F8BA4DC, $2039F90F, $20E70F32, $2192E09B, $223D66A8, $22E69AC8,
$238E7673, $2434F332, $24DA0A9A, $257DB64C, $261FEFFA, $26C0B162, $275FF452, $27FDB2A7,
$2899E64A, $29348937, $29CD9578, $2A650525, $2AFAD269, $2B8EF77D, $2C216EAA, $2CB2324C,
$2D413CCD, $2DCE88AA, $2E5A1070, $2EE3CEBE, $2F6BBE45, $2FF1D9C7, $30761C18, $30F8801F,
$317900D6, $31F79948, $32744493, $32EEFDEA, $3367C090, $33DE87DE, $34534F41, $34C61236,
$3536CC52, $35A5793C, $361214B0, $367C9A7E, $36E5068A, $374B54CE, $37AF8159, $3811884D,
$387165E3, $38CF1669, $392A9642, $3983E1E8, $39DAF5E8, $3A2FCEE8, $3A8269A3, $3AD2C2E8,
$3B20D79E, $3B6CA4C4, $3BB6276E, $3BFD5CC4, $3C42420A, $3C84D496, $3CC511D9, $3D02F757,
$3D3E82AE, $3D77B192, $3DAE81CF, $3DE2F148, $3E14FDF7, $3E44A5EF, $3E71E759, $3E9CC076,
$3EC52FA0, $3EEB3347, $3F0EC9F5, $3F2FF24A, $3F4EAAFE, $3F6AF2E3, $3F84C8E2, $3F9C2BFB,
$3FB11B48, $3FC395F9, $3FD39B5A, $3FE12ACB, $3FEC43C7, $3FF4E5E0, $3FFB10C1, $3FFEC42D,
$40000000);
function sin512(angle: Integer): Single;
asm
// if angle in upper half circle then
// EDX = -1
// map angle to 0..255 (lower half circle)
MOV EDX, 256
AND EDX, EAX
CMP EDX, 1
SBB EDX, EDX
XOR EDX, $FFFFFFFF
AND EAX, 255
// if angle > 128 (right quarter circle) then
// map angle to 0..128 (left quarter circle)
MOV ECX, 128
CMP ECX, EAX
SBB ECX, ECX
XOR EAX, ECX
SUB EAX, ECX
AND ECX, 256
ADD EAX, ECX
// lookup table
MOV EAX, DWORD PTR [EAX*4+SinLUT]
// adjust +/- of result
XOR EAX, EDX
SUB EAX, EDX
// change to float point result
PUSH EAX
FILD DWORD PTR [ESP]
FSTP DWORD PTR [ESP]
// adjust decimal, = value shr 30
SUB DWORD PTR [ESP], $0F000000
FLD DWORD PTR [ESP]
ADD ESP, 4
end;
function cos512(angle: Integer): Single; // cos(x) = size(x+quarter circle)
asm
ADD EAX, 128
JMP sin512
end;
type
TDoubleU = record
case Integer of
0: (f: Double);
1: (ul, uh: Cardinal);
end;
var
i: Integer;
y: TDoubleU;
r: double;
begin
for i := 0 to 128 do
begin
r := i / 256 * PI;
y.f := sin(r);
y.f := y.f + ldexp(1, 22);
SinLUT[i] := y.ul;
end;
end;