1

我需要计算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
 }  
}
4

2 回答 2

4

那里有几个问题。

  1. FMUL需要浮点参数,但您通过long.
  2. FICOM仅设置 FPU 标志,您必须将它们移动到 CPU 或使用FCOMI.
  3. JG正在检查错误的标志,您需要检查进位标志。
  4. 您的代码使浮点堆栈失衡。

奖励:由于 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"

见操作。

于 2012-11-04T02:13:55.033 回答
0

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)

于 2012-11-04T06:08:44.937 回答