Trying to write a log function

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

User avatar
intimidat0r
Posts: 73
Joined: Thu Aug 02, 2007 6:32 am UTC

Trying to write a log function

Postby intimidat0r » Thu Nov 22, 2007 2:26 am UTC

Code: Select all

int lollog(long i)
{
   /* returns log base 10 of i */
   
   long ans = 0;
   int n;
   for (n = 0; n < 10000; n++)
   {
      ans += (1 / (2 * n + 1)) * lolpow((double)(i - 1) / (double)(i + 1), 2 * n + 1);
   }
   printf("ans: %d\n", ans);
   return ans/1.15129255; // ans / (.5*ln(10))
}


Now, for some horrible reason this is returning 0 every time. You see that I'm printing out ans before dividing it by that number (ln(10)/2), but ans is 0 at that point according to the printout.

Now, when I remove the part where it's multiplied by lolpow() ans is not 0, which leads me to believe that lolpow() is returning zero. This is lolpow():

Code: Select all

long lolpow(double i, long w)
{
   /* find i^w ... only works for natural numbers*/
   
   long n = 0, result = 1;
   for (n = 0; n < w; n++)
   {
      result *= i;
   }
   return result;
}


Now I tested lolpow with the arguments 2 and 3 and it returned 8 as expected, so that works. I think I might have some kind of casting error somewhere, but I'm not very good at finding those. Does anything jump out at anybody?

And yes, there is a good reason that I'm rewriting all of these functions. I'm going to modify lollog() a little bit later to suit my problem (sacrificing accuracy for efficiency) and math.h didn't want to link for me so I decided to quickly rewrite the power function to suit my needs.

So, does anybody see an obvious problem with this? Thanks. :)

EDIT: Oh and if anybody is interested my logarithm function is based on this tidbit from Wikipedia:

Image
The packet stops here.

Rysto
Posts: 1460
Joined: Wed Mar 21, 2007 4:07 am UTC

Re: Trying to write a log function

Postby Rysto » Thu Nov 22, 2007 2:54 am UTC

ans += (1 / (2 * n + 1)) * lolpow((double)(i - 1) / (double)(i + 1), 2 * n + 1);

The bolded part uses integer division. You want 1.0 / (2 * n + 1).

User avatar
phlip
Restorer of Worlds
Posts: 7572
Joined: Sat Sep 23, 2006 3:56 am UTC
Location: Australia
Contact:

Re: Trying to write a log function

Postby phlip » Thu Nov 22, 2007 3:01 am UTC

Why is lolpow using an integer internally to store the result? And returning an integer?

I notice you're passing in (i-1)/(i+1)... a number slightly less than 1... so the first time it does result*=i in lolpow it'll set result to a number slightly less than 1... which will get truncated to 0. Resulting multiplications will do not very much.

Your test of lolpow(2.0,3) works because 2 is an integer... try lolpow(0.5,3) and you'll see you don't get 0.125...

[edit]
Also: ditch the fixed-iteration loop... rather, keep on looping until the difference between ans's on two iterations are less than some #define'd epsilon value. That'll be faster, and make it easy to twerk how accurate you want it to be.

Also also: Why have lollog take and return integers? This'd be much simpler if all you need is ints:

Code: Select all

int lollog(long val)
{
  int i = 0;
  while (val >= 10)
  {
    i++;
    val /= 10;
  }
  return i;
}
and I'm sure that can be optimised further.

Add the loop in lolpow, and you're heading in entirely the wrong direction if you're planning to optimise for speed...

Code: Select all

enum ಠ_ಠ {°□°╰=1, °Д°╰, ಠ益ಠ╰};
void ┻━┻︵​╰(ಠ_ಠ ⚠) {exit((int)⚠);}
[he/him/his]

User avatar
intimidat0r
Posts: 73
Joined: Thu Aug 02, 2007 6:32 am UTC

Re: Trying to write a log function

Postby intimidat0r » Thu Nov 22, 2007 3:47 pm UTC

Thank you both. I don't know how I could have missed all of those data type discrepancies. Or how I managed to overcomplicate my log function so much. :P
The packet stops here.

User avatar
Pathway
Leon Sumbitches...?
Posts: 647
Joined: Sun Oct 15, 2006 5:59 pm UTC

Re: Trying to write a log function

Postby Pathway » Mon Nov 26, 2007 8:39 am UTC

Don't use ints. Use doubles.
SargeZT wrote:Oh dear no, I love penguins. They're my favorite animal ever besides cows.

The reason I would kill penguins would be, no one ever, ever fucking kills penguins.

User avatar
Anpheus
I can't get any worse, can I?
Posts: 860
Joined: Fri Nov 16, 2007 10:38 pm UTC
Location: A privileged frame of reference.

Re: Trying to write a log function

Postby Anpheus » Mon Nov 26, 2007 8:46 am UTC

If you're using C/C++ you're reinventing the wheel, at least: C math.h reference.
Spoiler:

Code: Select all

  /###\_________/###\
  |#################|
  \#################/
   |##┌         ┐##|
   |##  (¯`v´¯)  ##|
   |##  `\ ♥ /´  ##|
   |##   `\¸/´   ##|
   |##└         ┘##|
  /#################\
  |#################|
  \###/¯¯¯¯¯¯¯¯¯\###/

User avatar
xyzzy
Meta-Titled
Posts: 263
Joined: Sun Mar 18, 2007 10:02 pm UTC
Location: Colossal Cave
Contact:

Re: Trying to write a log function

Postby xyzzy » Mon Nov 26, 2007 12:22 pm UTC

Anpheus wrote:If you're using C/C++ you're reinventing the wheel, at least: C math.h reference.


And? Reinventing the wheel can often be good for your understanding of something. It's a lot easier to grok code when you've written and implemented it yourself, not just read somebody else's.
"Wile E. Coyote was a theoretical mathematician." - Leliel
"Modern life can be so boring without elements of the bizarre or the fantastical. Hence, we have steampunk." - Me

User avatar
Cosmologicon
Posts: 1806
Joined: Sat Nov 25, 2006 9:47 am UTC
Location: Cambridge MA USA
Contact:

Re: Trying to write a log function

Postby Cosmologicon » Mon Nov 26, 2007 3:41 pm UTC

You're really not doing that logarithm formula justice unless you make the most of it.... In this case, it's best not to do the exponentiation every time. Instead, take some number p, initialize it to (z-1)/(z+1), and every time through the loop multiply it by ((z-1)/(z+1))^2. Then add to your total p / (2n + 1).

User avatar
Anpheus
I can't get any worse, can I?
Posts: 860
Joined: Fri Nov 16, 2007 10:38 pm UTC
Location: A privileged frame of reference.

Re: Trying to write a log function

Postby Anpheus » Mon Nov 26, 2007 7:09 pm UTC

If you want to grok logarithm implementations, try this out: http://www.icsi.berkeley.edu/pubs/techr ... 07-002.pdf

Pretty sweet implementation and I guarantee it's faster than the math.h one.
Spoiler:

Code: Select all

  /###\_________/###\
  |#################|
  \#################/
   |##┌         ┐##|
   |##  (¯`v´¯)  ##|
   |##  `\ ♥ /´  ##|
   |##   `\¸/´   ##|
   |##└         ┘##|
  /#################\
  |#################|
  \###/¯¯¯¯¯¯¯¯¯\###/

Dark Shikari
Posts: 113
Joined: Mon Jul 16, 2007 7:03 am UTC

Re: Trying to write a log function

Postby Dark Shikari » Tue Nov 27, 2007 9:57 am UTC

If you really want fun, write up some libraries for fixed-point integer-math versions of common complex floating point operations (log, sqrt, cos, etc) using a combination of fuzzy math and lookup tables :mrgreen:

Its quite good for programs that don't need flawless accuracy but need to run fast.

User avatar
evilbeanfiend
Posts: 2650
Joined: Tue Mar 13, 2007 7:05 am UTC
Location: the old world

Re: Trying to write a log function

Postby evilbeanfiend » Tue Nov 27, 2007 11:51 am UTC

Anpheus wrote:If you're using C/C++ you're reinventing the wheel, at least: C math.h reference.


presumably its homework or study rather than because he actually needs a log function
in ur beanz makin u eveel


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 12 guests