除以 nasm 时如何舍入商数?

How do you round quotients when dividing in nasm?

我不确定我是否使用了错误的数据类型或错误的指令或什么但是 div、idiv、fdiv 似乎都给我一个 0商。我想得到一些四舍五入到小数点后几位的小数。我认为我也为 division 使用了正确的寄存器。

mov ebp, 3          ;ebp = 3(constant) 
mov eax, edx            ;eax = edx(sum from previous calculation)
mov ecx,3           ;load upper half of dividend with zero
div ecx             ;divide double register ecx eax by 3

push eax
push msg6
call _printf
add esp, 8

我更改了 printf 中的格式,因此它以十进制格式显示,但仍然没有数字被 divided 看起来像?

div 执行(无符号)整数除法。这意味着你得到一个整数商和一个小于除数的余数。

如果你不想使用浮点数,你可以将余数乘以 10^n 再除以(n 将是你想要的小数位数)。这个新的商将是一个介于 0 和 10^n 之间的整数,但您可以用它来表示小数点后的 n 位数字。

要添加舍入,如果余数大于或等于 divisor/2。

,则应将此结果加 1

编辑

这(或多或少)是您手算小数的方法。 例如,要得到带两位小数的 18/7,第一个除法会生成商=2、余数=4.

接下来,如果你把余数乘以100再除

4*100/7 -> quotient=57, remainder=1

所以这个数字是 2.57(截断)。要考虑四舍五入,您应该查看以下数字是否小于 5。如果最后的余数小于 divisor/2,就会出现这种情况。考虑将 1 加到表示小数部分的数字可以传播到整数部分(例如计算 999/1000 有两位小数)。

mov ebp, 3          ;ebp = 3(constant)
mov eax, edx        ;eax = edx(sum from previous calculation)
mov ecx,3           ;load upper half of dividend with zero
div ecx             ;divide double register ecx eax by 3

看来你的除法是错误的!代码不符合评论的建议。
如果 EDX 保存了之前计算的总和,那么你应该将它移到 EAX 中,但同时清除 EDX 为即将到来的除法做准备。
正确的代码是这样的:

mov ebp, 3          ;ebp = 3(constant)
mov eax, edx        ;eax = edx(sum from previous calculation)
mov edx, 0          ;load upper half of dividend with zero
div ebp             ;divide edx:eax by 3

要使用 2 位小数,您可以在除法之前乘以 100,然后在显示为文本的结果的最后 2 个字符之前插入一个小数点字符。