汇编8086中如何将整数小数部分转换为对应的二进制小数部分

How to convert an integer fractional part to the correspondent binary fractional part in assembly 8086

例如,在纸上如果我有:

14.6875

在十进制表示法中,很容易获得二进制表示法的对应物:

1101.1011

.

这是因为:1*2^(3)+1*2^(2)+0*2^(1)+1*2^(0)+1*2^(-1)+0*2^(-2)+1*2^(-3)+1*2^(-4).

这个就可以了

我可以轻松实现二进制小数部分到十进制的转换。问题是相反的。如果我有

0.4321

例如,我如何在汇编 8086 中执行仅转换小数部分的过程:

4321

二进制表示法?

我应该这样做(或多或少):

(Iteration) Multiplicand    Multiplier  Carry
0           0.432100        2           0
1           0.864200        2           0
2           1.728400        2           1
3           1.456800        2           1
4           0.913600        2           0
5           1.827200        2           1
6           1.654400        2           1
7           1.308800        2           1
8           0.617600        2           0
9           1.235200        2           1
10          0.470400        2           0
11          0.940800        2           0
12          1.881600        2           1
13          1.763200        2           1
14          1.526400        2           1
15          1.052800        2           1
16          0.105600        2           0
17          0.211200        2           0
18          0.422400        2           0
19          0.844800        2           0
20          1.689600        2           1
21          1.379200        2           1
22          0.758400        2           0
23          1.516800        2           1
24          1.033600        2           1
25          0.067200        2           0
26          0.134400        2           0
27          0.268800        2           0
28          0.537600        2           0
29          1.075200        2           1
30          0.150400        2           0
31          0.300800        2           0
32          0.601600        2           0
33          1.203200        2           1
34          0.406400        2           0
35          0.812799        2           0
36          1.625599        2           1
37          1.251198        2           1
38          0.502396        2           0
39          1.004791        2           1
40          0.009583        2           0
41          0.019165        2           0
42          0.038330        2           0
43          0.076660        2           0
44          0.153320        2           0
45          0.306641        2           0
46          0.613281        2           0
47          1.226562        2           1
48          0.453125        2           0
49          0.906250        2           0
50          1.812500        2           1
51          1.625000        2           1
52          1.250000        2           1
53          0.500000        2           0
54          1.000000        2           1

同义考虑余数列(根据迭代)二进制的小数部分为:

0.4321 <=> 0.0011011101001111000011011000010001001101000000010011101

0.4321 <=> 0.0011011101001111[TRUNCATED WITH ROUNDING] .

我如何在 FLAT 8086 中以非常有效的方式完成所有这些工作?

(之前写的兽交给大家道歉。)

我post这里有一个可能的解决方案,也许它不是一个优雅的解决方案,我认为它可以改进很多,但至少基本概念似乎有效:

;PROCEDURE EXPLANATION      
;This procedure converts the 4 digits of decimal fraction
;in to correspondent binary notation.   

;DATA STRUCTURE USED

;REGISTERS USED

;EXTERNAL REQUIREMENTS

;OUTPUT

.model small
.stack
.data

;EXAMPLE DATA
int_example dw  0
frac_example dw 1234        ;num is: 0.6425

;REQUIRED DATA

;OUTPUT DATA
int_out dw  ?
frac_out dw ?

.code
.startup

          mov ax, int_example
          mov bx, frac_example
          call convert


.exit

convert proc
    call int_b_conversion
    call frac_b_conversion

    ret
convert endp

int_b_conversion proc

    ;to do
    mov int_out, ax

    ret
int_b_conversion endp 

frac_b_conversion proc
    mov ax, 5000d
    xor dx, dx ;REG used to store the binary fractional part
    mov cx, 08d ;almost 8 digits in an half REG
    cyc_01:   
        rol dx, 1
        cmp bx, ax
        jg greater_so_sub
        je break
        ;lesser so multiply
        rol bx, 1 ;mul by 2
            ;have 0
        jmp dodge_01
        greater_so_sub:
            inc dx ;have 1
            sub bx, ax
            rol bx, 1
        dodge_01:
    loop cyc_01

    jmp dodge_02


    break:
        sub cx, 1
        inc dx
        cyc_02:    
            rol dx, 1
            loop cyc_02
    dodge_02:

    mov frac_out, dx 

    ret
frac_b_conversion endp

end

此处更新,小数位数没有限制。

;PROCEDURE EXPLANATION      
;This procedure converts any digits (max 8) of a decimal fractional
;part in to correspondent binary notation.   
; In altre parole, questa funzione si occupa di convertire
; la parte frazionaria di un numero dalla notazione decimale
; a quella binaria.

;DATA STRUCTURE USED

;REGISTERS USED

;EXTERNAL REQUIREMENTS

;OUTPUT

.model small
.stack
.data

;EXAMPLE DATA
frac_example dw 654 ;num is: 0.1234
            ;i.e. the fractional part only

;REQUIRED DATA
some_number_010     dw      ?   ;This number, for example, requires
                                ;five digits to be represented in
                                ;the decimal notation. (INPUT)

number_of_digits_010        dw      ?       ;This is the OUTPUT of the
                                        ;procedure.
subtrahend_010 dw   ?

;OUTPUT DATA
frac_out dw ?

.code
.startup

          ;proc begin (argument passe by bx)
          mov bx, frac_example
          call frac_b_conversion
          ;proc end


.exit


frac_b_conversion proc 
    ;Nelle seguenti tre righe c'è l'algoritmo che serve per capire
    ;quante sono le cifre decimali del numero da convertire 
    ;e in base a questo valore assegna al sottraendo un valore pari a
    ; 5, 50, 500, 5000 o 50000
    mov some_number_010, bx
    call subtrahend_definition_010
    mov ax, subtrahend_010
    xor dx, dx ;REG used to store the binary fractional part
    mov cx, 08d ;almost 8 digits in an half REG
    cyc_01:   
        rol dx, 1
        cmp bx, ax
        jg greater_so_sub
        je break
        ;lesser so multiply
        rol bx, 1 ;mul by 2
            ;have 0
        jmp dodge_01
        greater_so_sub:
            inc dx ;have 1
            sub bx, ax
            rol bx, 1
        dodge_01:
    loop cyc_01

    jmp dodge_02


    break:
        sub cx, 1
        inc dx
        cyc_02:    
            rol dx, 1
            loop cyc_02
    dodge_02:

    mov frac_out, dx 

    ret
frac_b_conversion endp

subtrahend_definition_010        proc
        push ax
        push bx
        push dx

        mov ax, some_number_010
        mov bx, 9
        cmp ax, bx
        jg next_digit_count_1_010
        mov bx, 1       ;One digit.
        mov dx, 5
        mov subtrahend_010, dx
        jmp end_subtrahend_definition_010

next_digit_count_1_010:        
        mov bx, 99
        cmp ax, bx
        jg next_digit_count_2_010
        mov bx, 2       ;Two digit.
                mov dx, 50
        mov subtrahend_010, dx
        jmp end_subtrahend_definition_010

next_digit_count_2_010:        
        mov bx, 999
        cmp ax, bx
        jg next_digit_count_3_010
        mov bx, 3       ;Three digit.
                mov dx, 500
        mov subtrahend_010, dx
        jmp end_subtrahend_definition_010

next_digit_count_3_010:        
        mov bx, 9999
        cmp ax, bx
        jg next_digit_count_4_010
        mov bx, 4       ;Four digit.
                mov dx, 5000
        mov subtrahend_010, dx
        jmp end_subtrahend_definition_010

next_digit_count_4_010:        
        ;Five digit. (Last case: comparisons not needed).
        mov dx, 50000
        mov subtrahend_010, dx
        end_subtrahend_definition_010:
        pop dx
        pop bx
        pop ax      
        ret
subtrahend_definition_010        endp


end