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)*log 2 (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 ).
log b x = (log 2 b) -1 * log 2 x
The error stems from not noticing that the multiplier is a reciprocal. We can easily remove it because (log 2 b) -1 = log b 2 and then we substitute 10 for b . We therefore need as multiplier log 10 2 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 log e 2.
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.
The log conversion formula is log_b(x) = log_d(x)/log_d(b) or alternatively
log_b(x)*log_d(b) = log_d(x)
In your case I assume b = 2 and d = 10. So you want to push log_10(2) instead of log_2(10) onto the stack, since fyl2x compute SP(1) * log_2(SP(0)).
The command is FLDLG2 instead of FLDL2T.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.