Skip to main content
GameDev.net gamedev.net
🔒 Locked

Fun with logarithms

Started by lnxwndusr Mar 13, 2003 at 1:34 AM 13 replies 1.8k views
Original Post
lnxwndusr
lnxwndusr
Hey, I remember seeing somewhere this really slick way to calculate log2 (thats log with base 2) of any # quickly on a computer using c/c++ ... does such a function exist, and if so, is it better(meaning faster) to use it instead of doing log(x)/log(2) with math.h?
Strife
Strife
Yeah, there are ways of dealing with any kinds of logs directly. The log x/log n trick is just a quick way to do it mentally (or on paper) since we''re used to dealing with decimal systems.
lnxwndusr
lnxwndusr
I think I found it...


  
__inline DWORD Log2(DWORD val)
{
DWORD answer = 0;

while (val >>= 1)
answer++;

return answer;
}


Does this really work? I mean, I'm quite doubtful because it returns a DWORD and not a float.

[edited by - lnxwndusr on March 15, 2003 3:55:23 PM]
Zipster
Zipster
It really just gives you a rough estimate, because the bit shift restricts you to unsigned types that don''t have any special encoding format (float wouldn''t work for example), and it only returns an integer value. It will basically return the highest power of two that is less than or equal to the value you pass.

For the most precise value, you''re better off using ln(x)/ln(2). ln(2) is a constant, so store that somewhere and you won''t have to calculate it
Enselic
Enselic
It''d be faster to store 1/ln(2) and multiply ln(x) with that.


I am a signature virus. Please add me to your signature so that I may multiply.
Zipster
Zipster
Gotta scrape those nanoseconds wherever ya can
Jesper T
Jesper T
If you wrote ln(x)/ln(2) wouldn''t any decent compiler recognize 1/ln(2) as a constant and do the neccasary optimization?

YoshiN
YoshiN
quote:
Original post by Jesper T
If you wrote ln(x)/ln(2) wouldn''t any decent compiler recognize 1/ln(2) as a constant and do the neccasary optimization?


I wonder about that...I wouldn''t think so, because if you only used it once, then storing as a constant would actually be slower. Of course, the compiler may calculate the number of times it is used and then optimize...
-YoshiXGXCX ''99
63616C68h
63616C68h
Well, you say to yourself: some compilers do it and some others don''t, so I''ll do it myself and make it more poratable!
Keep coming back, because it's worth it, if you work it, so work it, you're worth it!
lnxwndusr
lnxwndusr
quote:
Original post by Zipster
It really just gives you a rough estimate, because the bit shift restricts you to unsigned types that don''t have any special encoding format (float wouldn''t work for example), and it only returns an integer value. It will basically return the highest power of two that is less than or equal to the value you pass.

For the most precise value, you''re better off using ln(x)/ln(2). ln(2) is a constant, so store that somewhere and you won''t have to calculate it


Any particular reason to use ln instead of log? There''s no mathematical difference between ln x/ln 2 and log x/log 2, but is there anything I don''t know about using c++?
Zipster
Zipster
I just figured the computer would have an easier time calculating the natural log because it can be expressed as a MacLaurin series, and the computer need only solve a few terms to get a good approximation. I suppose log10 could also be expressed in such a way due to the simple constant multiple ( 1/ln(10) ), however why do extra multiplications, eh?

[edited by - Zipster on March 16, 2003 5:14:11 PM]
Fruny
Fruny
I don''t know how the ln() and log() functions are actually implemented in the C library, but as far as the 8087 coprocessor is concerned, it''s just about the same thing :

FLDLG2 - push log10(2) on the FP stack
FLDLN2 - push ln(2) on the FP stack

FYL2X - computes Y*log2(X)

Thus log10(X) is

FLDLG2
FLD X
FYL2X

and ln(X) is

FLDLN2
FLD X
FYL2X




[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Bagel Man
Bagel Man
Actually, log(x) in C++ IS ln. To do a base 10 log, you use log10(x)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.