Reputation: 266
I need to calculate the sum of y(i) = sin(5*i)
in degree, where i
is increased every iteration. I need to calculate the sum before it becomes greater than 3, and find i
when the sum is greater.
With the code below, I get an infinite loop:
int main() {
float Sum=0;
long i=0;
long A=5;
long B=180;
int C=3;
_asm{
finit
m1:
inc i
fldpi ; load PI
fmul i ; PI * i
fmul A ; PI * i * 5
fdiv B ; PI * i * 5 / 180 (value in degree)
fsin ; sin(PI * i * 5 / 180)
fadd Sum ; counter all lopps result
ficom C ; check if lower than 3 go to m1
jg m1
}
}
Upvotes: 1
Views: 323
Reputation: 4209
Maybe it's offtopic, but using simple trigonometric identities, you can calculate answer without any loops for arbitrary sum value with a simple formula:
i=ceil(acos(cos(t/2)-2*result_sum*sin(t/2))/t-0.5)
where t is your step angle (5 degrees), result_sum - needed acumulated sum of consecutive sines (=3 in your case)
Upvotes: 0
Reputation: 58792
A few problems there.
FMUL
expects floating point arguments, but you pass long
.FICOM
only sets FPU flags, you have to move them to CPU or use FCOMI
.JG
is checking wrong flags, you need to check the carry flag.Bonus: Since 5*PI/180 is constant, you can precalculate that.
You could use some code like this (adjust for your compiler's syntax, this is for gnu assembler):
.intel_syntax noprefix
.globl main
main:
sub esp, 16 # allocate space for i, sum and fmt
mov dword ptr [esp+4], -1 # i
fild dword ptr [limit] # limit
fldz # sum
1:
inc dword ptr [esp+4] # i += 1
fild dword ptr [esp+4] # i
fmul qword ptr [factor] # i * factor
fsin
faddp # add to sum
fcomi st, st(1) # check if below limit
jb 1b
fstp qword ptr [esp+8] # store on stack for printf
fstp st(0) # remove limit from fpu stack
mov dword ptr [esp], offset fmt
call printf
add esp, 16 # clean up stack
xor eax, eax # return value
ret
.data
factor: .double .08726646259971647884 # 5 * PI / 180
limit: .int 3
fmt: .string "i=%d sum=%g\n"
Upvotes: 3