[英]How to calculate the logarithm of a number in MASM 32
How do I calculate the logarithm of a number in MASM 32?如何计算 MASM 32 中数字的对数?
For example if I have to calculate log(2.5), how will I do this?例如,如果我必须计算 log(2.5),我该怎么做?
I know this will involve fyl2x
and I have tried but I couldn't calculate it accurately.我知道这将涉及
fyl2x
,我已经尝试过,但无法准确计算。
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:在使用
FYL2X
指令之前,请阅读手册中的说明:
This instruction calculates (ST(1)*log 2 (ST(0))), stores the result in register ST(1), and pops the FPU register stack.
该指令计算 (ST(1)*log 2 (ST(0))),将结果存储在寄存器 ST(1) 中,并弹出 FPU 寄存器堆栈。 The source operand in ST(0) must be a non-zero positive number.
ST(0) 中的源操作数必须是非零正数。
The
FYL2X
instruction is designed with a built-in multiplication to optimize the calculation of logarithms with an arbitrary positive base ( b ).FYL2X
指令设计有内置乘法,以优化具有任意正基数 ( b ) 的对数计算。
log b x = (log 2 b) -1 * log 2 xlog 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 .
我们可以很容易地删除它,因为 (log 2 b) -1 = log b 2 然后我们用 10 代替b 。 We therefore need as multiplier log 10 2 which the FPU provides through its
FLDLG2
instruction.因此,我们需要 FPU 通过其
FLDLG2
指令提供的乘数 log 10 2。
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.要计算自然对数(又名“ln”),唯一的变化是使用
FLDLN2
(而不是FLDLG2
)来获得乘数 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.要计算二进制对数,唯一的变化是使用
FLD1
(而不是FLDLG2
)来获得微不足道的乘数 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. (*) 使用 DOS 显示数字解释了如何将 integer 转换为文本。 Look through the 'with DOS' mention and focus on the how and the why of the conversion itself.
查看“使用 DOS”的提及,并关注转换本身的方式和原因。
The log conversion formula is log_b(x) = log_d(x)/log_d(b) or alternatively对数转换公式为 log_b(x) = log_d(x)/log_d(b) 或
log_b(x)*log_d(b) = log_d(x) 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)).在你的情况下,我假设 b = 2 和 d = 10。所以你想将 log_10(2) 而不是 log_2(10) 推送到堆栈上,因为 fyl2x 计算 SP(1) * log_2(SP(0))。
The command is FLDLG2 instead of FLDL2T.该命令是 FLDLG2 而不是 FLDL2T。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.