Перевод чисел в системы счисления
Модератор: Andy
Это только вам решать, что использовать. Стек наверное проще будет в сохранении, но печатать оттуда не очень удобно.
Переделал прогу слегка. Разобрался с переводом в 2-ю систему счисления, всё работет отлично. Но теперь возникает другой вопрос с дробями. Я хочу число сразу распознать как целое или дробное. Для этого мне нужно пройтись по нему до запятой (если дробное) отделить целую часть от дробной. Целую часть можно сделать по уже написаной процедуре, а для дробной написать новую.
Подскажите пожалуйста, как разделить целую часть от дробной.
Подскажите пожалуйста, как разделить целую часть от дробной.
Вот что получилось:
Код: Выделить всё
.MODEL Small
.STACK 100h
.DATA
String db 16 dup (?),'$' ; Резервируем 16 байт для строки
StringEnd = $-1 ; Указывает на символ '$'
Number = 6219
Mes_1 db 0dh, 0ah, "Chislo 6219 v 16-y sisiteme schisleniya - ", "$"
Mes_2 db 0dh, 0ah, "Chislo 6219 v 8-y sisiteme schisleniya - ", " $"
Mes_3 db 0dh, 0ah, "Chislo 6219 v 2-y sisiteme schisleniya - ", " $"
.CODE
ORG 100h
Start:
mov ax,@data
mov ds,ax
mov es,ax
lea dx,Mes_1
mov ah,09h
int 21h
mov ax,Number
mov bx,16
std
lea di,StringEnd-10
call Perevod_num
mov ah,09h
lea dx,String
int 21h
lea dx,Mes_2
mov ah,09h
int 21h
mov ax,Number
mov bx,8
lea di,StringEnd-9
call Perevod_num
mov ah,09h
lea dx,String
int 21h
lea dx,Mes_3
mov ah,09h
int 21h
mov ax,Number
mov bx,2
lea di,StringEnd-1
call Perevod_num
mov ah,09h
lea dx,String
int 21h
mov ah,8
int 21h
ret
Break db 13,10
;---------------------------------Перевод числа-----------------------------
Perevod_num proc
push dx
push di
push cx
xor cx,cx
Proverka_num:
xor dx,dx
div bx
xchg ax,dx
add al,'0'
cmp al,'9'
jbe Cifra
add al,'A'-('9'+1)
Cifra:
stosb
xchg ax,dx
inc cx
test ax,ax
jne Proverka_num
pop cx
pop di
pop dx
ret
Perevod_num endp
end Start
Использовать FPU - сначала загрузить число в стек, потом выгрузить только целую часть в переменную. Не забыть предварительно задать FPU правило округления через управляющее слово. Дробная часть есть модуль разности исходного числа и его целой части. Перевод дробной части основан на последовательном умножении на 2 и сноса первой цифры после умножения. Подробнее в разделе "Алгоритмы" - там есть пример на Паскале." писал(а):Подскажите пожалуйста, как разделить целую часть от дробной.
It's a long way to the top if you wanna rock'n'roll
Алгоритм перевода вещественных чисел я знаю. Я просто хотел отделить целую и дробную часть для отдельного преобразования. Меня сейчас интересует как при загрузке числа в регистр я могу дойти до запятой, остановиться и отделить целую и дробную часть.
Насчёт FPU, никогда его не использовал, если есть другой вариант, подскажите пожалуйста, а если нет, примерчик использования FPU подкиньте.
Перевести в двоичную можно по-другому, если почитать про формат действительных чисел. Все они основаны на правиле Мантисса*2^Экспонента. Все числа имеют один знаковый бит, биты экспоненты и мантиссы варьируются в зависимости от разрядности действительного числа (32,64 или 80 бит), но обычно никто в это не вникает и делают чисто математически используя FPU.
Отделение целой и дробной части:
Отделение целой и дробной части:
Код: Выделить всё
YourNumber dd 27.32 ; ну например ))
YourIntValue dd ? ; Здесь будет целая
YourFracValue dd ? ; А здесь дробная часть
FPUCW dw ? ; тута управляющее слово
..... тра-ля-ля .....
..... туда-сюда .....
fnstcw FPUCW ; перепишем управляющее слово
fwait ; подождем пока он подумает
or FPUCW, 0F00h ; включим бит, теперь округление всегда к нулю
fldcw FPUCW ; закинем его обратно
fwait ; еще потупим немного
fld YourNumber ; грузим число
fist YourIntValue ; запишем его целую часть, начинает работать порядок округления
fisub YourIntValue ; вычитаем из числа его целую часть
fabs ; берем модуль, получили дробную часть
fstp YourFracValue ; выгружаем ее
It's a long way to the top if you wanna rock'n'roll
Спасибо за исчерпывающий ответ, но наверно для начала надо серьёзно почитать про работу с FPU