例如,在纸上,如果我有:
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 [圆角截止]
我如何在FLAT 8086中以非常有效的方式完成所有这些工作?
(我先前向所有人道歉,因为他们曾写过过兽性。)
答案 0 :(得分:0)
我在这里发布了一个可能的解决方案,也许它不是一个优雅的解决方案,我认为它可以改进很多,但至少基本概念似乎有效:
;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
答案 1 :(得分:0)
此处更新,没有小数位数限制。
;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