Перевод чисел в системы счисления

Низкоуровневое программирование портов, микроконтроллеров и т.д.

Модератор: Andy

airyashov
Сообщения: 416
Зарегистрирован: 02 ноя 2007, 10:31

08 апр 2008, 11:55

Это только вам решать, что использовать. Стек наверное проще будет в сохранении, но печатать оттуда не очень удобно.
Pegasik
Сообщения: 11
Зарегистрирован: 08 апр 2008, 09:52

09 апр 2008, 11:37

Переделал прогу слегка. Разобрался с переводом в 2-ю систему счисления, всё работет отлично. Но теперь возникает другой вопрос с дробями. Я хочу число сразу распознать как целое или дробное. Для этого мне нужно пройтись по нему до запятой (если дробное) отделить целую часть от дробной. Целую часть можно сделать по уже написаной процедуре, а для дробной написать новую.
Подскажите пожалуйста, как разделить целую часть от дробной.
Pegasik
Сообщения: 11
Зарегистрирован: 08 апр 2008, 09:52

09 апр 2008, 11:40

Вот что получилось:

Код: Выделить всё

.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
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

09 апр 2008, 12:53

&quot писал(а):Подскажите пожалуйста, как разделить целую часть от дробной.
Использовать FPU - сначала загрузить число в стек, потом выгрузить только целую часть в переменную. Не забыть предварительно задать FPU правило округления через управляющее слово. Дробная часть есть модуль разности исходного числа и его целой части. Перевод дробной части основан на последовательном умножении на 2 и сноса первой цифры после умножения. Подробнее в разделе "Алгоритмы" - там есть пример на Паскале.
It's a long way to the top if you wanna rock'n'roll
Pegasik
Сообщения: 11
Зарегистрирован: 08 апр 2008, 09:52

09 апр 2008, 14:44

Алгоритм перевода вещественных чисел я знаю. Я просто хотел отделить целую и дробную часть для отдельного преобразования. Меня сейчас интересует как при загрузке числа в регистр я могу дойти до запятой, остановиться и отделить целую и дробную часть.
Pegasik
Сообщения: 11
Зарегистрирован: 08 апр 2008, 09:52

09 апр 2008, 15:05

Насчёт FPU, никогда его не использовал, если есть другой вариант, подскажите пожалуйста, а если нет, примерчик использования FPU подкиньте.
Аватара пользователя
somewhere
Сообщения: 1837
Зарегистрирован: 31 авг 2006, 17:14
Откуда: 71 RUS
Контактная информация:

09 апр 2008, 16:14

Перевести в двоичную можно по-другому, если почитать про формат действительных чисел. Все они основаны на правиле Мантисса*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
Pegasik
Сообщения: 11
Зарегистрирован: 08 апр 2008, 09:52

09 апр 2008, 16:38

Спасибо за исчерпывающий ответ, но наверно для начала надо серьёзно почитать про работу с FPU
Ответить