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!
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.