Числа с плавающей запятой
Встроенный сопроцессор FPU позволяет производить любые вычисления, но вывести результаты вычислений не так просто. Для этого требуется или использование библиотеки fpu.lib, входящей в состав стандартной поставки masm32 или использование специальных функций, например, типа описанной в руководстве по FPU (тоже прилагается, дает два десятичных знака). Но можно использовать еще более короткую функцию, построенную на основании такого алгоритма: берем число с плавающей запятой, отбрасываем дробную часть, оставшееся целое преобразуем в строку. К строке добавляем символ-разделитель (например, точку), оставшуюся дробную часть умножаем на единицу со столькими нулями, сколько необходимо знаков после запятой и повторяем операцию. К строке с целой частью и символом-разделителем добавляем строку с десятичными знаками. Осталось куда-нибудь вывести результат. Код функции:
; #########################################################################
; FloattoA1 PROTO :DWORD,:DWORD
; #########################################################################
FloattoA1 PROC source:DWORD,destination:DWORD
LOCAL Flags :WORD,tmpval:DWORD
LOCAL buff[12]:byte
.data
dec_mult dd 10000
fMtStrinG db "%lu",0
.code
fstcw Flags
or Flags,0000110000000000b
fldcw Flags
fld[source]
frndint
fist[tmpval]
invoke wsprintf,destination,ADDR fMtStrinG,tmpval
invoke lstrcat,destination,ADDR point
finit
fld[source]
fisub[tmpval]
fimul[dec_mult]
fabs
frndint
fist[tmpval]
invoke wsprintf,ADDR buff,ADDR fMtStrinG,tmpval
invoke lstrcat,destination,ADDR buff
ret
FloattoA1 ENDP
; #########################################################################
Установка флагов процессора необходима для правильного режима округления, а именно - отброса дробной части. Если этого не сделать, будет произведено обычное округление, которое устанавливается при инициализации процессора. После этого вернутся к обычному округлению можно командой finit и продолжить работу с дробной частью числа. Константа dec_mult задает число десятичных знаков, в приведенном примере их четыре. Подобную функцию удобно применять для контроля промежуточных результатов вычислений. Функция вызывается командой
invoke FloattoA1, переменная типа float, адрес буфера
Переменная типа float, передаваемая функции, должна быть объявлена как глобальная.


