Actualmente la forma en que lo hago es la siguiente

mov bx,divisor
div bx
mov quotient,ax
mov ax,dx
mul hundred ;--r * 100 to show 2 floating point, r * 1000 to show 3...
div bx
mov float,ax
mov floatr,dx

Y luego, podría incrementar la flotación dependiendo del valor de floatr. Luego, generaré el cociente, '.', Float. Esto funciona para la mayoría de los números o, más bien, números con flotantes que comienzan con números distintos de cero. Por ejemplo, 1/100 = 0.01, sin embargo, mi programa generará 0.1, no generará el cero extra.

1
J Xkcd 31 dic. 2019 a las 17:29

2 respuestas

La mejor respuesta

El principio es el mismo que en mi respuesta aquí. Y aquí está mi implementación para MASM de 16 bits:

.MODEL small, C
.386

.STACK 100h

.CODE

main PROC
    mov ax, 1                   ; Dividend
    mov bx, 100                 ; Divisor
    xor dx, dx                  ; Clear high 16 bit of dividend
    div bx                      ; Result: AX, remainder in DX

    call WriteDec

    mov al, '.'                 ; Decimal point
    call WriteChar

    mov cx, 10                  ; Maximal 10 digits
    L1:
    imul ax, dx, 10             ; AX = DX * 10 i.e. New dividend = Old remainder * 10
    xor dx, dx                  ; Clear the high part of dividend
    div bx                      ; AX rem. DX = DX:AX / BX
    call WriteDec
    dec cx
    jz SHORT E
    test dx, dx                 ; Is there a remainder?
    jnz L1                      ; Yes - once more

    E:
    mov ax, 4C00h
    int 21h
main ENDP

WriteDec PROC USES AX BX CX DX DI DS
    LOCAL decimal[6]:byte

    mov dx, ss
    mov ds, dx
    lea di, decimal             ; LOCAL target string decimal

    mov bx, 10                  ; divisor
    xor cx, cx                  ; CX=0 (number of digits)

    First_Loop:
        xor dx, dx              ; Attention: DIV applies also DX!
        div bx                  ; DX:AX / BX = AX remainder: DX
        push dx                 ; LIFO
        inc cl                  ; increment number of digits
        test  ax, ax            ; AX = 0?
        jnz First_Loop          ; no: once more

    Second_Loop:
        pop ax                  ; get back pushed digit
        or al, 00110000b        ; AL to ASCII
        mov byte ptr [di], al   ; save AL
        inc di                  ; DI points to next character in string DECIMAL
        loop Second_Loop        ; until there are no digits left

        mov byte ptr [di], '$'  ; End-of-string delimiter for INT 21 / FN 09h

    lea dx, decimal
    mov ah, 09h
    int 21h

    ret
WriteDec ENDP

WriteChar PROC USES AX DX
    mov dl, al
    mov ah, 02h
    int 21h
    ret
WriteChar ENDP

END main

Por cierto: feliz año nuevo

2
rkhb 31 dic. 2019 a las 17:12

Escriba su función de salida entera para producir un número fijo de dígitos de salida, sin detenerse cuando la división repetida por 10 produce cero.

Esto le dará los ceros iniciales que necesita para usar este entero como la parte fraccionaria de una fracción decimal.

Por cierto, esto es punto fijo, no punto flotante. Estás escalando para poder manejar un número fijo de lugares después del decimal. Una representación en coma flotante implicaría almacenar un exponente y un significado / mantisa, no partes enteras y fraccionarias separadas.

0
Peter Cordes 31 dic. 2019 a las 17:13