在我的程序中,我试图计算两个整数的平均值,然后舍入数字。例如,如果平均值为-22.5,则将舍入为-23。 validInputs是从用户收集的有效输入的数量,并且始终是正整数,而validSum将始终是负整数,因为它只添加负整数。然而,当比较余数时,我没有得到正确的舍入结果,并且想知道为什么。
编辑:我将建议的更改设为-5,但仍然遇到相同的错误。我相信我的错误必定是一个逻辑问题。
mov eax, validSum
cdq
mov ebx, validInputs
idiv ebx
mov validAverage, eax
mov intRemainder, edx
cmp edx, -5 ; compare the remainder to -5
jg display ; if greater than -5 we know not to round/decrement
dec validAverage
答案 0 :(得分:1)
如果你只是除以2,解决方案很容易。 IDIV
在这种情况下只给出三个可能的余数:{-1,0.1},这意味着:
-1:总和为负数,小数点后面的数字为-0.5,平均值必须减1,即avg = avg + (-1)
。
0:没有余数,平均值已经正确舍入,即avg = avg + 0
。
1:总和为正数,余数为0.5,必须加1,即avg = avg +1
。
正如您所看到的,不需要进行冗长的比较,您可以将余下的EDX
添加到EAX
:
; Only valid for EBX=2
mov eax, validSum
cdq ; EAX -> EDX:EAX
mov ebx, validInputs
idiv ebx ; EDX:EAX / EBX -> EAX remainder EDX
mov validAverage, eax ; Save result
add validAverage, edx ; Add -1 or 0 or 1
jmp display ; End of Rounding
除此之外,余数与十进制数的小数部分无关。将它与5或-5直接比较是完全错误的。您必须先获得第一个小数位。在长时间的分工中你会添加"结尾为0,然后除以除数。同样在这里:乘以十(=最后加0)并除以EBX
。现在你可以将结果除以5得到上面的三元组:{-1,0.1}
...
idiv ebx ; EDX:EAX/EBX
mov validAverage, eax ; Save result
mov eax, edx
add eax, eax ; A quick way to multiply by 10
lea eax, [eax + eax * 4] ; EAX * 10 = EAX * 2 + EAX * 8
cdq ; EAX -> EDX:EAX
idiv ebx ; EDX:EAX / EBX -> EAX remainder EDX
mov ebx, 5
cdq ; EAX -> EDX:EAX
idiv ebx
add validAverage, eax ; Add -1 or 0 or 1
jmp display ; End of Rounding
您可以将EAX*10/EBX/5
转换为EAX*2/EBX
:
mov eax, validSum
cdq ; EAX -> EDX:EAX
mov ebx, validInputs
idiv ebx ; EDX:EAX / EBX -> EAX remainder EDX
mov validAverage, eax ; Save result
imul eax, edx, 2 ; EAX = EDX * 2
cdq ; EAX -> EDX:EAX
idiv ebx ; EDX:EAX / EBX
add validAverage, eax ; Add -1 or 0 or 1
jmp display ; End of Rounding