Page 1 of 1

#1 Help! (Programming)

Posted: Fri Dec 16, 2005 6:56 am
by Surlethe
So, I wrote a program:

Code: Select all

#include <iostream>
#include<cmath>
using namespace std;
int main()
{
    int n;
    int l;
    float x;
    int y;
    int k;
    int P;
    l=1;
    n=1;
    cout<<"Please enter an upper bound"<<endl;
    cin>>k;
    while(n<=k)
               {
               x=n/(floor(sqrt(n))-l);
               y=n/(floor(sqrt(n))-l);
               while(x!=y)
                          {
                          l--;
                          }
               cout<<abs(n/y-y)<<endl;
               n++;
               }
    cout<<"Finished!  Thank you.  Press any key to exit."<<endl;
    cin>>P;
    if(P=0)
             {
             return 0;
             }    
    return 0;
}
It compiles just fine, but when I try to run it, it borks. What am I doing wrong?

#2

Posted: Fri Dec 16, 2005 11:09 am
by Destructionator XV
What exactly, do you want it to do?

Just tried to compile it, and gcc choked:
a.cpp: In function `int main()':
a.cpp:18: error: call of overloaded `sqrt(int&)' is ambiguous
/usr/include/bits/mathcalls.h:157: error: candidates are: double sqrt(double)
/usr/include/c++/3.3.6/cmath:550: error: long double
std::sqrt(long double)
/usr/include/c++/3.3.6/cmath:546: error: float std::sqrt(float)
a.cpp:19: error: call of overloaded `sqrt(int&)' is ambiguous
/usr/include/bits/mathcalls.h:157: error: candidates are: double sqrt(double)
/usr/include/c++/3.3.6/cmath:550: error: long double
std::sqrt(long double)
/usr/include/c++/3.3.6/cmath:546: error: float std::sqrt(float)

#3

Posted: Fri Dec 16, 2005 11:14 am
by Surlethe
Given an upper bound, it should spit out the difference between the two closest factors of ever integer between 0 and the upper bound.

#4

Posted: Fri Dec 16, 2005 11:20 am
by Destructionator XV
Crap dude!

Code: Select all

               while(x!=y)
                          {
                          l--;
                          }
If x != y, that loop is endless!

#5

Posted: Fri Dec 16, 2005 11:21 am
by Surlethe
l-- decrements l, right? Eventually, since x and y are both functions of l, x will equal y, right?

#6

Posted: Fri Dec 16, 2005 11:35 am
by Destructionator XV
Yes it does, but, you didn't change the values of x any in inside the loop. Assignment with the = is a one time thing, so .

x=n/(floor(sqrt(n))-l);
//x is now assigned the value of n/(floor(sqrt(n))-l), but it will stay the same until is is assigned again.
y=n/(floor(sqrt(n))-l);
//same as happened with y
while(x!=y)
{
l--;
//l decreases by one here, but x and y are never set to = anything, so they stay the same.
}

This is what you are looking for:

Code: Select all

               x=n/(floor(sqrt(n))-l);
               y=n/(floor(sqrt(n))-l);
               while(x!=y)
                          {
                          l--;
               x=n/(floor(sqrt(n))-l); /* be sure to reset x and y now that l is different */
               y=n/(floor(sqrt(n))-l);
                          }
               cout<<abs(n/y-y)<<endl;
               n++;
               }
You see?

#7

Posted: Fri Dec 16, 2005 11:42 am
by Surlethe
Yeah, I see. Thanks.

It compiles and runs, but now it spits out the wrong numbers. :???:
And the algorithm should work, so there's something wrong with the way I'm translating the algorithm into the program.

Also, is there a way I can get it to spit out ordered pairs of the form (n,f(n))?

#8

Posted: Fri Dec 16, 2005 11:57 am
by Dark Silver
-stares at the GeekCode Speak and mind blows up-

#9

Posted: Fri Dec 16, 2005 12:00 pm
by Destructionator XV
Yeah, change
cout<<abs(n/y-y)<<endl;

to

cout<<"("<<n<<","<<abs(n/y-y)<<")"<<endl;

And that abs(n/y-y) : is that correct? I noticed your value of x is never used, in fact, x and y are always equal! Should they be?

#10

Posted: Fri Dec 16, 2005 12:12 pm
by Surlethe
Destructionator XV wrote:Yeah, change
cout<<abs(n/y-y)<<endl;

to

cout<<"("<<n<<","<<abs(n/y-y)<<")"<<endl;
OK. Thanks.
And that abs(n/y-y) : is that correct? I noticed your value of x is never used, in fact, x and y are always equal! Should they be?
The reasoning is x is a float and y is an int, so y truncates at the decimal point; thus, they're only equal when they're both an integer. Then, the first time they're equal is when the expression n/(floor(sqrt(n))-l) is the factor of n closest to the square root of n; then, at that point, x==y and, so, either x or y could be used in n/y-y.

Since y(y+m)=n, and we want m (the difference between the two factors y and y+m) to be the output, we solve: y(y+m)=n <=> n/y=y+m <=> m=n/y - y.

Is that reasoning correct?

#11

Posted: Fri Dec 16, 2005 12:28 pm
by Destructionator XV
Oh, I see. Your reasoning is correct, but your code has one small error: when evaluating, the types will all be cast. The first variable listed sets the type (also follows order of operations). Look at your division:

n/(floor(sqrt(n))-l);

Lets simplify that just a wee bit by letting d = (floor(sqrt(n))-l). d is a float.

x = n / d

x is a float, and it is assigned to the int n divided by the float d. Since the int came first, the float is converted to an int then the division occurs.

That means x will always be truncated to an integer.

To solve the problem, explicitly cast n as a float, like so:

x = (float) n / d;

Alternativly, you could declare n as a float at the top of your program instead of an int.

Also, in your comparison between x and y, it should be a float automatically, but just to be sure, I would change it to
while(x!= (float) y)

Being explicit will reduce the possibility of error.

#12

Posted: Fri Dec 16, 2005 12:39 pm
by Surlethe
Destructionator XV wrote:Oh, I see. Your reasoning is correct, but your code has one small error: when evaluating, the types will all be cast. The first variable listed sets the type (also follows order of operations). Look at your division:

n/(floor(sqrt(n))-l);

Lets simplify that just a wee bit by letting d = (floor(sqrt(n))-l). d is a float.

x = n / d

x is a float, and it is assigned to the int n divided by the float d. Since the int came first, the float is converted to an int then the division occurs.

That means x will always be truncated to an integer.

To solve the problem, explicitly cast n as a float, like so:

x = (float) n / d;

Alternativly, you could declare n as a float at the top of your program instead of an int.
OK. That makes sense.
Also, in your comparison between x and y, it should be a float automatically, but just to be sure, I would change it to
while(x!= (float) y)

Being explicit will reduce the possibility of error.
The key point of the comparison between x and y is that they're not equal until they're both integers; if y is a float, then they'll be equal immediately and lead to a wrong result.

I added your suggestions to the code; the first four outputs are right, but then for n>=5, it gives me the wrong numbers. I'm not sure what's wrong with my algorithm. :???:

#13

Posted: Sat Dec 17, 2005 9:04 pm
by Destructionator XV
Surlethe wrote:The key point of the comparison between x and y is that they're not equal until they're both integers; if y is a float, then they'll be equal immediately and lead to a wrong result.
In this situation, it wouldn't matter, since y was initally stored as an int: it's decimal value was already discarded. However, your reasoning is again correct.
I added your suggestions to the code; the first four outputs are right, but then for n>=5, it gives me the wrong numbers. I'm not sure what's wrong with my algorithm. :???:
Not sure. I'm looking into it now.

#14

Posted: Sat Dec 17, 2005 9:14 pm
by Destructionator XV
Am I correct is thinking that the answer for any perfect square should be 0? And any prime number would be n-1?

#15

Posted: Sun Dec 18, 2005 10:37 am
by Surlethe
Destructionator XV wrote:Am I correct is thinking that the answer for any perfect square should be 0? And any prime number would be n-1?
Yes. As it stands, the program now maps everything above n=5 to n-1.

#16

Posted: Sun Dec 18, 2005 1:44 pm
by Pcm979
*Looks back and forth*

My brain hurts.

#17

Posted: Sun Dec 18, 2005 8:46 pm
by Surlethe
I reduced it to a single while loop to run just one value of n, but it only seems to work randomly. :???: I'm swiftly losing patience.

Code: Select all

#include <iostream>
#include<cmath>
using namespace std;
int main()
{
    int n;
    int l;
    float x;
    int y;
    int P;
    l=0;
    cout<<"Please enter a number"<<endl;
    cin>>n;
    x=n/(floor(sqrt(n))-l);
    y=(int)n/(floor(sqrt(n))-l);
          while(x!=(int)y)
                     {
                     x=n/(floor(sqrt(n))-l--); 
                     y=n/(floor(sqrt(n))-l--);
                     }
               cout<<"("<<n<<","<<abs(n/y-y)<<")"<<endl; 
    cout<<"Finished!  Thank you.  Press any key to end."<<endl;
    cin>>P;
    if(P!=0)
             {
             return 0;
             }    
    return 0;
}
It returns only numbers less than three, for some reason. Everything else just b0rks the program, and there's no output; I just close the window.