鱼C论坛

 找回密码
 立即注册
查看: 2966|回复: 4

求大数阶乘,思路应该没错,但是求15以上的阶乘时会卡住

[复制链接]
发表于 2020-4-30 15:23:14 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  .MODEL SMALL,STDCALL
  .386
   

  .DATA
  digit db 0
  n     db ?
  i     db 0
  j     db 0
  num   db 0
  array db 10000 dup(0)


   
  .CODE
  main proc
    ;装载数据段地址
    mov ax,@data
    mov ds,ax

;-----------------把输入存到n中
    mov  bx, 0
    Newchar:
      mov  ah, 1
      int  21h 
      sub  al, 30h 
      jl  endinput
      cmp  al, 9    
      jg  endinput
      cbw  
      xchg   ax, bx
      mul   cx
      xchg  ax, bx    
      add   bx, ax 
      jmp   newchar 
    endinput:
    mov n,bl
;-----------------


    mov al,1
    mov array[0],al

    mov al,1
    mov digit,al

    mov ch,0
    mov cl,n
    sub cl,2
    firstloop:
      ;i = n - cx = al
      mov ah,0
      mov al,n
      sub ax,cx
      mov i,al
      ;num = 0 = dl,dh也用了
      mov dh,0
      mov dl,0
      mov num,dl

      ;------------ j = 0 = bx
      mov bx,0
      secondloop:
        ; --------temp=a[j]*i+num;
        mov al,i
        mov ah,array[bx]
        mul ah;->ax
        add ax,dx
        mov dh,10;暂时借用dh,一会儿要再改回dh=0
        div dh
        ; ----------a[j]=temp%10;
        mov array[bx],ah
        ; -----------num=temp/10;
        mov dl,al
        mov num,dl
        mov dh,0

        add bx,1
        mov j,bl
        cmp bl,digit
        jl secondloop

      whileloop:
        mov dl,num
        mov dh,0
        cmp dx,0
        je tonext
        mov ax,dx
        mov dh,10;暂时借用dh,一会儿要再改回dh=0
        div dh
        mov dh,0
        mov j,bl
        mov bh,0;原本bx是j,暂时改成digit
        mov bl,digit
        mov array[bx],ah
        ; num=num/10;
        mov dl,al
        ; digit++;
        add bl,1
        mov digit,bl
        mov bl,j;还原bx的值j

        cmp dx,0
        jne whileloop

      tonext:
        mov al,i
        add al,1
        mov i,al
        sub cx,1
        cmp al,n
        jle firstloop




      ; ------------逆序打印一下
      mov bh,0
      mov bl,digit
      sub bl,1
      
    printloop:
      MOV  DL,array[bx]
      add dl,30h
      mov ah,2
      int 21h
      sub bx,1
      cmp bx,0
      jnl printloop

      jmp exit;

    exit:
      mov ah,4ch
      int 21h
    main endp
    end main
原文链接:https://blog.csdn.net/lisp1995/article/details/52403507

编译用的是MASM,我基本是完全照搬上边这篇文章的思路,只是c语言改写成汇编
(应该有些地方不用把寄存器数据写回到数据段,我这里为了跑通写的繁琐了,之后还可以简化)


问题:
求14以下结果输出正确,但是算15阶乘就会卡住
推测一,有些变量用db存储,会溢出,但是digit在算15!时应该只比10多一点,其他变量就更小了
推测二,来自dosbox的未知限制?这个不确定,我再debug试试

既然能算出14!,按照链接中这个思路应该更大的也可以算,虽然代码有点长,各位能提出建议我会很感谢的

result.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-4-30 15:33:57 From FishC Mobile | 显示全部楼层
超范围了啊
更换算法
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-30 15:38:23 | 显示全部楼层
wp231957 发表于 2020-4-30 15:33
超范围了啊
更换算法

这个算法就是为了解决超范围的问题吧(?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-30 15:43:28 From FishC Mobile | 显示全部楼层
DarrenTitor 发表于 2020-4-30 15:38
这个算法就是为了解决超范围的问题吧(?

你这代码16位的?,不都是eax   ebx   ecx   edx
64位的,没玩过,不知道是啥
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-26 08:48:07 | 显示全部楼层
超过位数了,就使用多个寄存器或者多个内存单元分别存放数的高位和低位,目前没有必要做这种题目,理解循环指令的工作流程即可。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-6 00:37

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表