jmp start
mess1 db 'Enter 1st number: $'
mess2 db 0a,0d, 'Enter 2nd number: $'
nextline db 0a,0d, '$'
start:
mov ax, 03
int 10h
mov dx, offset mess1
call printstring
call input
sub al, 30h
push ax
mov dx, offset mess2
call printstring
call input
mov bl, al
mov dx, offset nextline
call printstring
sub cl, 30h
sub bl, 30h
pop ax
mov ah, 0
aad
div bl
mov dl, al
add dl, 30h
push ax
call printchar
mov dl, '.'
call printchar
mov ah, 0
pop ax
mov dl, ah
add dl, 30h
call printchar
int 20h
input:
mov ah, 1
int 21h
ret
printstring:
mov ah, 9
int 21h
ret
printchar:
mov ah, 2
int 21h
ret
它在余数为0时起作用,但只有当方程有余数时,余数才会显示错误的数字。
1条答案
按热度按时间rta7y2nd1#
余数是分数的分子。例如,"5/3 = 1,余数为2"(因为"5-(1 * 3)= 2"),所以真实结果为"1 + 2/3"(或"商+余数/除数")。请注意,许多分数是循环小数,"1 + 2/3"为数字2.66666666 ...
最简单的显示方法是将其显示为分数(例如打印余数、"/"符号和除数)。
将其打印为小数;您可以重复地将"余数/除数"乘以10并提取整数部分。Eidogg."2 * 10/3 = 6,余数为2",这样您就可以打印"6"并使用新的余数再次进行打印,对于本例来说,新的余数将是相同的,所以你最终会重复打印"6"(直到你因为其他原因停止打印--例如,因为你把它限制在3位数)。你会得到"1 * 10/8 = 1余数为22 * 10/8 = 2,余数为4;4 * 10/8 = 5,余数为0 ",得到数字1、2和5。
另一个问题是,这将向零截断,而人类更喜欢"四舍五入"-例如,对于"5/3",你最终会打印"5.666",而人类会想要"5.667"。为了解决这个问题,如果你在小数点后计算3位数,你会想要在开始时将0.0005添加到原始余数中。并且为了对分数进行该运算,其最终是交叉乘法-例如"余数/除数+1/2000 =(余数 * 2000)/(除数 * 2000)+除数/(除数 * 2000)=(余数 * 2000 + 1)/(除数 * 2000)"。
换句话说如果在将分数转换为三位小数之前执行"余数=余数 * 2000 + 1"和"除数=除数 * 2000",则会得到正确的四舍五入结果。* 注意:在某些情况下,这种舍入可能会改变整数部分-例如,值3.99987654321应该显示为"4.000",但如果您不小心,您会显示为"3.000"。幸运的是,您不必担心这种情况(因为除数总是从1到9的数字)。*
装配中;可能如下所示(NASM语法,未测试):
请注意,跟踪变量范围非常重要(例如,正如我在上面的注解中所做的那样),以确保没有溢出错误。例如,从10到180000的整数值将不适合16位(并且不适合AX这样的16位寄存器),我们只是幸运地使用了指令集,在这些情况下可以很容易地使用一对寄存器("dx:ax"或"DX中的最高16位和AX中的最低16位")。