I searched the net for alternatives and found fast_sin from https://www.gamedev.net/forums/topic/62 ... oximation/

it turns out to be much faster and more accurate (about 3 decimal digits), here are the times on my PC

Code: Select all

`32-bit, gen gcc -Wc -O2`

time for FB sin = 18.01501279999502

sum = -6.369349492274523e-013

time for fast_sin = 4.04145359992981

sum = 2.114974861910923e-013

time for _Sin6th = 11.92606279999018

sum = 67.97632024315362

64-bit gen gcc -Wc -O2

time for FB sin = 42.23232729989104

sum = 8.659739592076221e-015

time for fast_sin = 3.331463000038639

sum = 2.114974861910923e-013

time for _Sin6th = 6.449131899978966

sum = 67.97632024315362

one surprise was the much longer execution time for FB x64 but more accurate, the sum should be 0

Code: Select all

`'https://www.freebasic.net/forum/viewtopic.php?f=7&t=26248`

Function _Sin6th(fX As Double) As Double

asm

jmp _Sin6th_Start

_Sin6th_Mul: .double 683565275.57643158

_Sin6th_Div: .double -0.0000000061763971109087229

_Sin6th_Rnd: .double 6755399441055744.0

_Sin6th_Start:

movq xmm0, [fX]

mulsd xmm0, [_Sin6th_Mul]

addsd xmm0, [_Sin6th_Rnd]

movd ebx, xmm0

lea eax, [ebx*2+0x80000000]

sar eax, 2

imul eax

sar ebx, 31

lea eax, [edx*2-0x70000000]

lea ecx, [edx*8+edx-0x24000000]

imul edx

xor ecx, ebx

lea eax, [edx*8+edx+0x44A00000]

imul ecx

cvtsi2sd xmm0, edx

mulsd xmm0, [_Sin6th_Div]

movq [Function], xmm0

End Asm

End Function

'https://www.gamedev.net/forums/topic/621589-extremely-fast-sin-approximation/

function fast_round(byval x as double) as long

dim MAGIC_ROUND as const double = 6755399441055744.0

union fast_trunc

d as double

type

lw as long

hw as long

end type

end union

dim fast_trunc as fast_trunc

fast_trunc.d = x

fast_trunc.d += MAGIC_ROUND

return fast_trunc.lw

end function

'https://www.gamedev.net/forums/topic/621589-extremely-fast-sin-approximation/

function fast_sin(byval x as double) as double

dim PI as const double = 3.14159265358979323846264338327950288

dim INVPI as const double = 0.31830988618379067153776752674502872

dim A as const double = 0.00735246819687011731341356165096815

dim B as const double = -0.16528911397014738207016302002888890

dim C as const double = 0.99969198629596757779830113868360584

dim k as long

dim x2 as double

k = fast_round(INVPI * x)

x -= k * PI

x2 = x * x

x = x * (C + (x2 * (B + (A * x2))))

if k mod 2 then

x = -x

end if

return x

end function

dim as double t, y

t=timer

y=0

for x as double=-214748364 to 214748364

y += sin(x)

next

print "time for FB sin = ";timer-t

print "sum = ";y

t=timer

y=0

for x as double=-214748364 to 214748364

y += fast_sin(x)

next

print "time for fast_sin = ";timer-t

print "sum = ";y

t=timer

y=0

for x as double=-214748364 to 214748364

y += _Sin6th(x)

next

print "time for _Sin6th = ";timer-t

print "sum = ";y