首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >汇编代码以确定一个数字是否完美。

汇编代码以确定一个数字是否完美。
EN

Stack Overflow用户
提问于 2022-04-20 00:28:56
回答 1查看 303关注 0票数 0

我正在尝试编写一个程序来确定一个数字是否是完美

程序报告的数字6是完美的,但对于数字28,它也是一个完美的数字,它表明它不是完美的。

你能帮上忙吗?

代码语言:javascript
复制
.data 
    msg1 db 13,10," Enter a number:$"
    perf db 13,10,"The number is perfect number $"
    nperf db 13,10,"The number is not perfect number $"
    num dw ?
    x dw 0
.const

.code


 ppp proc _x$:word

        uses bx,dx,ax,cx
        mov bx,0
        mov ax,_x$
        mov cx,ax
        dec cx  
        cmp ax,1        
        je perfecto     
           next:
           cwd
           div cx
           cmp dx,0
           je sum 
           dec cx
           jmp next
                       
            sum:
            add bx,cx
            dec cx
            cmp cx,0
            jnz next
            mov ax,_x$
            cmp ax,bx
            je perfecto
            call puts,offset nperf
             jmp done
             perfecto:
            call puts,offset perf

    
       
       done:
        ret
 
      ppp endp

    .startup
        call puts,offset msg1
        call endl
        call getint
        mov num,ax
        call ppp,num
        finish2:
    .exit
end
EN

回答 1

Stack Overflow用户

发布于 2022-04-20 18:41:21

cmp ax,1 je完美

你为什么认为1是一个完美的数字?维基百科文章使用了以下定义:

在数论中,完美数是一个正整数,等于它的正除数之和,不包括数本身。例如,6有除数1、2和3(不包括本身),1+2+3= 6,所以6是一个完美的数字。

数字1只有一个除数(1),这是定义想要你排除的。剩下的是什么,这显然不等于数字1。

此外,维基百科的那篇文章还提到,可能没有、奇数、、完美数字

代码失败的原因

代码背后的思想是将输入的数字N除以范围N-1,1中的所有数字。在找到零余数后,将当前的除数添加到和变量BX中。这不是最优的,但它可以工作。但是,由于您忽略了重新加载原来的数字,所以您并不是在除以输入的数字,而是从前面的除法中得到的商。它似乎适用于数字6,因为它的3个除数密切跟踪,是循环的最后3次迭代。

代码语言:javascript
复制
            AX   DX
 6 /  5  -> Q=1  R=1
 1 /  4  -> Q=0  R=1
 0 /  3  -> Q=0  R=0  -> BX=0+3=3
 0 /  2  -> Q=0  R=0  -> BX=3+2=5
 0 /  1  -> Q=0  R=0  -> BX=5+1=6   OK

现在考虑28:

代码语言:javascript
复制
            AX   DX
28 / 27  -> Q=1  R=1
 1 / 26  -> Q=0  R=1
 0 / 25  -> Q=0  R=0  -> BX=0+25=25
 0 / 24  -> Q=0  R=0  -> BX=25+24=49
 0 / 23  -> Q=0  R=0  -> BX=49+23=72
 0 / 22  -> Q=0  R=0  -> BX=72+22=94
 0 / 21  -> Q=0  R=0  -> BX=94+21=115   ???
...

解决方案

  • 最好从输入数字的一半开始除法。较大的除数永远不会产生零余数。
  • 最好不要把最后的除法除以1,它总是产生一个零余数。最后只有inc bx。或者更好地将运行的和初始化为1而不是0。
  • 最好使用单个条件分支指令来编写除法循环,而不是使用条件退出分支和无条件重复分支。
代码语言:javascript
复制
  mov  bx, 1       ; Running sum
  mov  cx, _x$     ; Inputted number
  shr  cx, 1       ; First divisor is N/2
  jz   NotPerfect  ; N=0 or N=1
next:
  mov  ax, _x$     ; RELOADING NUMBER
  xor  dx, dx
  div  cx
  dec  cx          ; (*)
  test dx, dx
  jnz  next

  add  bx, cx
  inc  bx          ; (*) Because CX got already decremented
  cmp  cx, 1
  ja   next
代码语言:javascript
复制
            AX   DX
28 / 14  -> Q=2  R=0  -> BX=1+(13+1)=15
28 / 13  -> Q=2  R=2
28 / 12  -> Q=2  R=4
28 / 11  -> Q=2  R=6
28 / 10  -> Q=2  R=8
28 /  9  -> Q=2  R=10
28 /  8  -> Q=3  R=4
28 /  7  -> Q=4  R=0  -> BX=15+(6+1)=22
28 /  6  -> Q=4  R=4
28 /  5  -> Q=5  R=3
28 /  4  -> Q=7  R=0  -> BX=22+(3+1)=26
28 /  3  -> Q=9  R=1
28 /  2  -> Q=14 R=0  -> BX=26+(1+1)=28  OK
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71932794

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档