-3

I'm a complete beginner. I've written a small C# program on SharpDevelop. Here it is:

double i, j;

for(i=1; i<=30; i+=(1/60))
{
    for(j=1+1/60; j<=30; j+=(1/60))
    {
        if(Math.Abs(Math.Log(i)/Math.Log(j)-0.63092975357)<=0.00001)
        {
            Console.WriteLine("ln("+i+")   ln("+j+")");
        }
    }
}

        Console.ReadKey(true);

My program is supposed to find the i and the j for which ln(i)/ln(j)=0.63092975357 (for example) i and j are necessarily equal to n/60 and m/60 respectively, where n and m are positive integers. (I know I can use type int instead of type double, but I would like to make it work with the type double.)

But it doesn't work. When I click on "Run Project", the black screen pops up, but nothing happens... And SharpDevelop doesn't point out any errors...

So what mistakes did I make? And how to fix my program?

leppie
  • 115,091
  • 17
  • 196
  • 297
user50746
  • 281
  • 2
  • 4
  • 10
  • 1
    I suggest setting a breakpoint on the first `for` loop, step through it and see what happens. – Stefan Oct 24 '14 at 06:39
  • 1
    Not sure why you get downvoted, your problem is pretty obvious. see my answer for details. – Alex Anderson Oct 24 '14 at 06:42
  • First you need to get a set of values that you know should produce your desired result. Then check your formula. If it does work, the problem is in the `i`, `j` values. If not, well, fix the formula. Repeat. – Andrei V Oct 24 '14 at 06:42
  • Possible duplicate of [Division returns zero](http://stackoverflow.com/questions/9288904/division-returns-zero) – Maksim Simkin Jan 04 '17 at 07:02

4 Answers4

4

Integer division.

1/60 = 0

You need 1 / 60.0d instead.

When you divide by an integer you will get an integer result. Integers are not capable of storing decimals.

When you are doing 1/60 you expect 0.0166666666666667 but it is infact 0.

This code now works

double i, j;

for(i=1; i<=30; i+=(1/60d))
{
  for(j=1+1/60d; j<=30; j+=(1/60d))
  {
      if(Math.Abs(Math.Log(i)/Math.Log(j)-0.63092975357)<=0.00001) 
          Console.WriteLine("ln("+i+")   ln("+j+")"); 
  }
}

EDIT: *Probally worth mentioning, writing 60d ensures that 60 is a double type. Hence your division now retuns a double *

Adam Calvet Bohl
  • 1,009
  • 14
  • 29
Alex Anderson
  • 840
  • 5
  • 11
  • 1
    I agree. let me elaborate on Alex's answer - literals (numbers) are compiled for what they represent (your case: 60 is an integer number. if you'd write 60d or 60. with the '.' you'll let the compiler know you meant the double value of 60. – Muli Yulzary Oct 24 '14 at 06:45
1

The mistake I see here is using 1/60 expecting that to be a double representing 0.0166... It is actually 0, because both 1 and 60 are integers and this becomes integer division. Try using 1.0/60.0, 1/60.0 or 1.0/60, 1/60d or any combination of these and that should fix it, assuming your algorithm is mathematically correct.

Once you fix this, you might start seeing a large number of lines printing some results since your program won't terminate until the loops are finished, even thought it might already be printing lots of data. You can fix it by add a flag variable (a bool) to terminate the outer loop and break to terminate the inner one.

1

You could make your life a little easier by keeping your loops and integers and then working out the doubles as and when you need them for the log functions.

Also by adding a Console.Write() before the ReadKey you can see when the the loop finishes.

for(var i=1; i<=1800; i++)
{
    for(var j=1; j<=1800; j++)
    {
        double di = double(i)/60.0; 
        double dj = double(j)/60.0;

        if(Math.Abs((Math.Log(di)/Math.Log(dj))-0.63092975357)<=0.00001)
        {
            Console.WriteLine("ln("+di+")   ln("+dj+")");
        }
    }
}

Console.WriteLine("Press any key to continue");
Console.ReadKey(true);
Code Uniquely
  • 6,356
  • 4
  • 30
  • 40
0

1 / 60 performs integer division and it always generates 0 as a result. It always discards the fractional part.

From / Operator (C# Reference)

When you divide two integers, the result is always an integer. For example, the result of 7 / 3 is 2.

That's why your first for loop will be like;

for(i = 1; i <= 30; i += 0)

since i never get increased, it will never be 30 and that's why this generates an infinite loop.

As a solution, you need to use floating-point division instead.

for(i = 1; i <= 30; i += (1 / 60f))
{
    for(j = 1+1/60f; j <= 30; j += (1 / 60))

Besides on that, I suggest you to read Eric Lippert's How to debug small programs which you can easily find what is wrong in your code without even asking here.

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364