How do I calculate the logarithm of a number in MASM 32?
For example if I have to calculate log(2.5), how will I do this?
I know this will involve fyl2x
and I have tried but I couldn't calculate it accurately.
This is what I tried but it prints no result.
INCLUDE Irvine32.inc
; .data is used for declaring and defining variables
.data
num real8 3.324 ; the data I want to convert
res real8 ?
.code
main PROC
fldl2t ; st: log2(10)
fld num ; st: log2(10) num
fyl2x ; st: log10(num)
fstp res ; store to out and pop
call CrLf
call CrLf
exit
main ENDP
END main
I see that you have copied the code from an existing answer. Sadly, that answer contains errors!
Before using the FYL2X
instruction, read the description in the manual:
This instruction calculates (ST(1)*log2(ST(0))), stores the result in register ST(1), and pops the FPU register stack. The source operand in ST(0) must be a non-zero positive number.
The
FYL2X
instruction is designed with a built-in multiplication to optimize the calculation of logarithms with an arbitrary positive base (b).
logbx = (log2b)-1 * log2x
The error stems from not noticing that the multiplier is a reciprocal. We can easily remove it because (log2b)-1 = logb2 and then we substitute 10 for b. We therefore need as multiplier log102 which the FPU provides through its FLDLG2
instruction.
num REAL8 3.324
res REAL8 ?
...
FLDLG2 ; ST0 = log10(2)
FLD num ; ST1 = log10(2), ST0 = num
FYL2X ; ST0 = log10(num)
FSTP res
To calculate the natural logarithm (aka 'ln'), the only change would be to use FLDLN2
(instead of FLDLG2
) to obtain the multiplier loge2.
To calculate the binary logarithm, the only change would be to use FLD1
(instead of FLDLG2
) to obtain the trivial multiplier 1.
An algorithm that converts a floating point number into its textual representation is not all that simple, but maybe next fixed-point trick is all that you need:
num REAL8 3.324
quad dq ?
kilo dw 1000
...
FLDLG2 ; ST0 = log10(2)
FLD num ; ST1 = log10(2), ST0 = num
FYL2X ; ST0 = log10(num)
FIMUL kilo ; ST0 = 1000 * log10(num)
FISTP quad
...
(*) Displaying numbers with DOS explains how converting an integer to text works. Look through the 'with DOS' mention and focus on the how and the why of the conversion itself.