I hope this is not a banal question but I just can't find the problem in my code. I keep getting the error message "expression result unused" and "relational comparison result unused" when trying to compile my code.
The problem is with the following function:
bool is_inside(double x, double y){
if(sqrt(pow((x-0,5),2)+pow((y-0,5),2))<0,5){
return true;
}
return false;
}
which gets called in this function:
void estimate_func(unsigned long nsteps, unsigned long nstep_print){
unsigned long i;
unsigned long in_circle=0;
double x,y;
double curr_pi,curr_s;
for(i=0;i<nsteps;i++){
x=drand48();
y=drand48();
if(is_inside(x,y)){ // call!!!
in_circle++;
}
if(!(i%(nstep_print+1))){
curr_pi=(double) 4*(in_circle/(i+1));
curr_s=4*(sqrt((curr_pi/4)*(1-curr_pi/4)/(double)(i+1)));
printf("\t%lu\t%.6lf\t%.6lf\t%.6lf\n", i+1, curr_pi ,
curr_pi-M_PI, curr_s);
}
}
}
Has anyone an idea what I am doing wrong?
The problem is, essentially, that C source code is not locale-aware. Clearly, in your locale, the comma is used as the decimal separator, so you write ½ as 0,5. C doesn't do it that way. It always uses the period as the decimal separator, so ½ is always 0.5.
The comma does something different in C. It's actually a distinct operator known as the comma operator. It evaluates both its operands, discards the result of the first, and returns the result of the second. So, taking into account the operator precedence, what you currently have is seen by the compiler as:
if((sqrt(pow(((x-0),5),2)+pow(((y-0),5),2))<0),5){
which, evaulating the inner comma operators, gives:
if((sqrt(pow(5,2)+pow(5,2))<0),5){
and evaluating the outer comma operator reduces to:
if(5){
which the compiler can tell is trivially true, and is therefore warning you about it. The return false block will never be reached.
The correct way to write the code would be:
bool is_inside(double x, double y){
return (sqrt(pow((x - 0.5), 2) + pow((y - 0.5), 2)) < 0.5);
}
Notice that I have also elided the pointless if statement. This does exactly the same thing, and is easier to read. A comparison always returns either 1 (true) or 0 (false) in C, so its result can be used directly as a Boolean.
I've also added spaces, because let that code breathe!
What maybe you want to do is this:
bool is_inside(double x, double y){
if(sqrt(pow((x-0.5),2)+pow((y-0.5),2))<0.5){
return true;
}
return false;
}
Change the , to . if you want to represent floating point numbers (real numbers)
Just refactoring your code a little bit:
bool is_inside(double x, double y){
return sqrt(pow((x-0.5),2) + pow((y-0.5),2)) < 0.5); // changing , to .
}
void estimate_func(unsigned long nsteps, unsigned long nstep_print){
unsigned long i, in_circle=0;
double x, y, curr_pi, curr_s;
for(i = 0; i < nsteps; i++){
x = drand48();
y = drand48();
if(is_inside(x,y)) in_circle++;
if(!(i % (nstep_print + 1))){
curr_pi = (double) 4 * (in_circle / (i + 1));
curr_s = 4 * (sqrt((curr_pi / 4) * (1 - curr_pi / 4) / (double)(i + 1)));
printf("\t%lu\t%.6lf\t%.6lf\t%.6lf\n", i + 1, curr_pi ,
curr_pi - M_PI, curr_s);
}
}
}
Always try as much as possible to reduce the number of lines in your code. Beautiful code is short and concise. Check out these exercises http://divostar.com/learn-c
Related
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main()
{
int i,a,n,r;
n=12345;
r=0;
for(i=4;i>=0;i--)
{
a=n%10;
n=n/10;
r=r+a*pow(10,i);
}
printf("%d",r);
return 0;
}
Current output - 54320
Expected output - 54321
Please advise on what I may change in my code to reflect the correct output.
The pow function returns a value of type double. Because this is a floating point type, the result it returns will not always be exact.
What's happening in this case is that on the last iteration of the loop pow(10, 0) returns a value slightly less than 1. This results in the right hand side of r=r+a*pow(10,i); to similarly be slightly less than 54321. When this value is then assigned to r, which is of type int, it gets truncated.
Rather than using the pow function here, use the following:
r=r*10+a;
This shifts the current digits in r over by 1, then adds the newest digit to the end. Also, rather than using a for loop, use while (n>0) instead. Then it doesn't matter how many digits you have.
while (n>0)
{
a=n%10;
n=n/10;
r=r*10+a;
}
Here is a simplified version of your algorithm:
void reverse_digits(int a) {
int b = 0;
while (a > 0) {
b = b * 10 + a % 10;
a /= 10;
}
printf("%d\n", b);
}
As for converting to character arrays as mentioned in the comments it's worth to notice that the convertion function will do similar arithmetic operations in order to convert the integer to character array, so doing the reversing using integers seems more convenient.
I am studying how to program and have recently been working on a problem that calculates the total of 2 entered numbers from min to max. For example, if someone entered the numbers 4, 7. The calculation would be 4+5+6+7=22.
I've attempted what i think would be the definition of recSum but obviously it is wrong as I get a segmentation fault. What is wrong with my definition?
/* Define the recursive function */
int recSum (int x, int max)
{
int incrementalSum = 0;
if (x == max)
{
return x; /* Exit if summated lower to upper numbers */
}
else
{
return (x + recSum(x++, max)); /* My recursive call */
}
} /* End of function call */
*new code is shown above, sorry, i used the wrong code.
Your code has 3 important problems
The expression
incrementalSum = x + x++;
is undefined, read this for more information
Your function is not recursive, a recursive function calls it self until a condition happens where it should end.
Also, noting that I am not an irrational "don't ever use goto person", this is precisely why some people advice against using goto.
The reason your code doesn't work is this line:
return x + recSum(x++, max);
x++ increments x but returns the previous value, so in the recursive calls it never increments and you never reach the base case. Like an infinite loop. You have to replace x++ with ++x in order to give any result, even though it won't be correct. ++x is modifying x so it will alter the final sum of x + recSum. You'd better use:
return x + recSum(x + 1, max);
See What is the difference between ++i and i++?
It seems you mean the following
int recSum(int x, int max)
{
return max < x ? 0 : x + recSum( x + 1, max );
}
Or it would be even better to declare the return type of the function like long long int.
long long int recSum(int x, int max)
{
return max < x ? 0 : x + recSum( x + 1, max );
}
The function can be called like
printf( "%lld\n", recSum( 4, 7 ) );
As for your function then it exits in the first call
int recSum(int x, int max)
{
int incrementalSum = 0;
recCall: if (x < max)
return incrementalSum;
^^^^^^^^^^^^^^^^^^^^^
because usually it is called when x is less than max. So the function does not make sense. Moreover the function is not recursive because it does not call itself.
I just started learning C and I faced the following problem:
in the first /recursive step/ I do not understand why we cannot simply return multiply(x, y)? Why do we need to add a value to y and only then return it?
The code is below.
Thank you!
#include <stdio.h>
unsigned int multiply(unsigned int x, unsigned int y)
{
if (x == 1)
{
/* Terminating case */
return y;
}
else if (x > 1)
{
/* Recursive step */
return y + multiply(x-1, y);
}
/* Catch scenario when x is zero */
return 0;
}
int main() {
printf("3 times 5 is %d", multiply(3, 5));
return 0;
}
If you return multiply(x, y), you will loop forever on the same call parameters. To have proper recursion, you have to reduce the problem to a simpler case. That simpler case is to reduce the multiplier by 1.
Recursion is simply doing the same operations with smaller inputs. Can we express multiplication of two numbers with smaller numbers ? Sure ! Finding the way to do this is finding a recursive definition of multiplication. First we will try to express x*y with a smaller x, like x-1.
From the simple fact that :
(x-1)*y = x*y - y
we find :
x*y=(x-1)*y + y
Remember that we will always have to find a stoping step, here we know that
0*y=0
and we're done. This gives us even a simpler form of a recursive mul function as the one given by #RobertEagle.
But let us take the thing further. x-1 is smaller than x, as y-1 is smaller than y. Exploring this fact gives us :
(x-1)*(y-1)=x*y-x-y+1
x*y = (x-1)*(y-1) + x + y - 1
This time the stopping step would be "if x or y is 0 then the result is 0". Translating this into code :
unsigned multiply(unsigned x, unsigned y)
{
if ( (x==0) || (y==0) )
return 0;
else
return x+y-1+multiply(x-1, y-1);
}
This sort of recursion is not quite efficient because we do not express the recursion with something really smaller. What if we try to halve one of the parameters ?
If x is even we can write :
x*y=2*(x/2)*y=(x/2)*(2*y)
If x is odd we can write :
x*y=(x-1+1)*y=(x-1)*y+y=((x-1)/2)*(2*y)+y
Multiplying (resp. dividing) by 2 can be achieved with left (resp. right) shifting :
unsigned multiply(unsigned x, unsigned y)
{
if (x==0)
return 0;
else if (x%2==0)
return multiply(x>>1, y<<1);
else
return y+multiply((x-1)>>1, y<<1);
}
This method will take less steps than the first one. The "more" you're getting smaller, the "more" you're getting faster, in general.
If you didn't add the value, it would simply return y as the final result of the top most recursive call.
X * Y = X, Y times
e.g. 4 * 5 = 4 + 4 + 4 + 4 + 4
This logic is expanding that evaluation, and just returning the last value would only evaluate to Y one time.
Every recursive function is made up of 2 elements:
The repetitive condition
The stopping condition
Without a stopping condition, the program would enter an infinite loop.
In this case, it would mean the program would continually call beyond x == 1.
Instead of stopping calling itself at x == 1, the program would also call multiply(-1,y), multiply(-2,y) ... to infinite.
Ultimately, you need to sum the y for x times. And to do this you need to return x times the value of y. And in this case, the repetitive condition adds y for x-1 times and for the stopping condition you only need one more time.
You also could have done it this way:
#include <stdio.h>
unsigned int multiply(unsigned int x, unsigned int y)
{
if (x == 0)
{
/* Terminating case */
return 0;
}
else if (x > 0)
{
/* Recursive step */
return y + multiply(x-1, y);
}
}
int main() {
printf("3 times 5 is %d", multiply(3, 5));
return 0;
}
Here you can see the repetitive is concerted with adding the y for exactly x times. Logically, the stopping condition would require to return 0, because we don't need to add anymore the y value. We already have added it for x times.
I'm trying to calculate a simple approximation to an integral by dividing it up into a step function, easy stuff. The problem starts when I simply try to do a division. Here is my code:
double integrand(int a, double div, int n) {
int i;
double sum, val;
val = 1.0/div;
for(i = 0; i < div; i++) {
sum = sum + (pow(i*val, n)/(i*val + a)) * val;
}
return sum;
}
Here div is actually an integer, I tried bringing it into the integrand function originally as an integer and typecasting it to a double inside the function, with the same result. When I debug the code, div can be say, 100, yet val will return something ludicrous like -7.2008557565654656e+304. As far as I'm aware the rest of the code is correct, but I just cannot figure this out, what's going on?!
You never initialized sum:
double sum = 0, val;
Right now, you're using it in your calculation with an uninitialized value, and hence getting some garbage results.
First initialize sum and then use it. Otherwise it will invoke undefined behavior.
I am pretty flabbergasted as to why my code got stuck at the 16512th iteration even though it seemed to have no syntactical problems. Here is the code:
#include <stdio.h>
/*C version of Newton-Raphson method*/
float sqrt(float num);
main()
{
int i;
for (i = 1; i <= 100000; i++) {
printf("%d: %.3f\n", i, sqrt(i));
}
}
float sqrt(float num)
{
float guess, e, upperbound;
guess = 1;
e = 0.001;
do
{
upperbound = num / guess;
guess = (upperbound + guess) / 2;
} while (!(guess * guess >= num - e &&
guess * guess <= num + e));
return guess;
}
The code is supposed to find the square-root of all numbers from 1 to 100000 using the Newtonian-Raphson method, but nothing happened after the 16152th iteration. I am using the Developer Command Prompt for VS2012 to compile my scripts, if that information is of any help. Enlightenment will be gladly appreciated.
Honestly, when I posted mycomment, it was more a hunch than real knowledge. The algorithm was valid, so something must be making the while loop not terminate, and since you were properly using epsilons, we were hitting the limits from the float.
#PaulR's comments make it make more sense. The sqrt of 16512 is 128.499027233672... Float has fairly limited precision, so it wasn't getting anything within .001 of that number. It makes even more sense if you think of an even bigger number, e.g. sqrt(123455555.54321) (which is 11111.11111). Floating point precision won't necessarily even get you to the 11111, let alone 11111.111.
Changing to double "fixes" this, but just kicks the can down the road. Somewhere later on, we'd have the same precision issue, and this algorithm should work on any size number.
#mrbratch brings up the robust solution - define your tolerance as a percentage of the number. If you set e = num * 0.00001, your loop will always complete. Obviously, you can play with epsilon and tweak it to your satisfaction. And note, for big numbers, this can give you an integer that's not even the closest int to the right answer.
I can't speak for python, but I can confirm that javascript uses double precision.
As already explained in the comments, the problem is because you can't have that much precision (0.001) with any number. In particular, when the number is large enough, only the most important digits are saved. See the IEEE 754 standard if you want more information about how it works. http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
Now, I'd recommend that you use a percentage of error for the tolerance:
float sqrt(float num)
{
float guess, e, upperbound;
guess = 1;
e = 0.001;
do
{
upperbound = num / guess;
guess = (upperbound + guess) / 2;
} while (!(guess * guess / num >= 1 - e &&
guess * guess / num <= 1 + e));
return guess;
}
Simple adjustment
Use relative Floating Point precision, not absolute.
There area as many FP representable numbers between 0.001 and 0.002 as between 1,000 and 2,000. So when calculating square root, the iterations should depend on the local relative error.
Do not use absolute error bounds like e = 0.001, but relative ones. Code then runs just fine.
// e = 0.001;
e = 0.001 * num;
[edit] I know see #Scott Mermelstein has a similar comment.
IMHO, the squaring causes loss of precision:
#include <stdio.h>
/*C version of Newton-Raphson method*/
float mysqrt(float num); /* avoid conflicts with built-in sqrt() if any */
int main(void)
{
int i;
for (i = 1; i <= 100000; i++) {
printf("%d: %.3f\n", i, (double)mysqrt(i)); /* cast to double, since printf() is varargs */
}
return 0;
}
float mysqrt(float num)
{
float newguess, e, oldguess;
e = 0.001;
newguess = 1.0;
do
{
oldguess = newguess;
newguess = (num/oldguess + newguess ) / 2;
/* compare tor the previous value; avoid squaring */
} while (newguess / oldguess > (1+e) || oldguess / newguess > (1+e) );
// } while (newguess < oldguess -e || newguess > oldguess +e); // "mostly works"
return newguess;
}