我需要计算y(i) = sin(5*i)
度的总和,其中i
每次迭代都会增加。我需要在总和大于3之前计算总和,并在总和更大时找到i
。
使用下面的代码,我得到一个无限循环:
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
}
}
答案 0 :(得分:4)
那里有一些问题。
FMUL
需要浮点参数,但是您传递了long
。FICOM
仅设置FPU标志,您必须将它们移至CPU或使用FCOMI
。JG
正在检查错误的标志,您需要检查进位标志。奖励:由于5 * PI / 180是常数,因此可以预先计算。
您可以使用这样的代码(根据编译器的语法进行调整,这适用于gnu汇编程序):
.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"
答案 1 :(得分:0)
也许它是offtopic,但是使用简单的三角标识,你可以用一个简单的公式计算答案而不需要任何和值的循环:
i=ceil(acos(cos(t/2)-2*result_sum*sin(t/2))/t-0.5)
其中t是你的步角(5度),result_sum - 需要连续正弦的累计和(在你的情况下= 3)