This is a code that I wrote to find the cube root of a number using Newton Raphson. However, it always shows the answer as -1#IND0. Can you help me find what is wrong with this code?
#include <stdio.h>
int main()
{
float x_0,x,x_m,n;
int m,i=0;
printf("Enter integer you wish to find the cube root of: ");
scanf("%f",&n);
printf("\nEnter your first guess and number of steps: ");
scanf("%f %d",&x_0,&m);
x_m=(1/3)*((2*x_0)+(n/(x_0*x_0)));
// printf("\nx_m=%f\nx_0=%f\nm=%d",x_m,x_0,m);
while( i<m)
{
x=x_m;
x_m=(1/3)*((2*x)+(n/(x*x)));
i++;
}
printf("\nThe cube root of %.0f is approximately %.5f",n,x_m);
return 0;
}
Before the loop starts, m_x will be zero since (1/3) is zero (integer division).
On the first iteration, (n/(x*x)) is then a poll as x will be zero. That accounts for the output being -1#IND0.
The fix, as always, is to remove all those extra parentheses that folk always seem to put in:
x_m=(2*x + n/(x*x))/3;
&c. (although your duplication of the Newton Raphson formula is unsatisfactory - as you have to put the fix in two places.). Because x is a floating point type, all the arithmetic will be performed in floating point, due to the sensible rules of type promotion.
After you've fixed this, bin it and use cbrt, from the C standard library header math.h.
Before the while you have
x_m=(1/3)*((2*x_0)+(n/(x_0*x_0)));
Since 1/3 will yield 0, x_m will be 0. And then you have
x_m=(1/3)*((2*x)+(n/(x*x)));
where you use x*x as a quantity to divide n with. Since x is 0, the result will have an undefined behavior. Try to make sure the amount you divide with is not 0, but a valid value, start with (1.0/3).
Related
I'm trying to build a calculator, which input a number n it can automatically output the sum of
1/2+2/2 +1/3+2/3+3/3 +...+1/n+2/n+...+n/n and for each denominator, print the result once.
The calculator will restart and ask for input after output the final result of 1/2+2/2 +1/3+2/3+3/3 +...+1/n+2/n+...+n/n .And when the the user decides to stop the program enter 0.
for input=3 ,the output is sum =1 ,sum=2 ,yet I expected it to be sum=3/2, sum=7/2
Here's the program
#include <stdio.h>
int main(){
printf("Please enter the max denominator:\n");
int i,j,n;
int sum=0;
do{
scanf("%d",&n);
for (j=2;j<=n;j++){
for(i=1;i<=j;i++){
sum+= i/j;
if (i==j){
printf("sum=%d\n",sum);
break;
}
}
}
} while (n!=0);
return 0;
}
EDIT: revised part due to advice
int i,j,n;
double sum=0.0;
do{
scanf("%d",&n);
sum=0.0;
for (j=2;j<=n;j++){
for(i=1;i<=j;i++)
sum+=(double)i/j;
printf("sum=%lf\n",sum);
}
} while (n!=0);
return 0;
}
Your program is working with integers. i, j, n, and sum are all integers. This means they cannot encode numbers like 3/2 or 7/2.
So what happens when you divide two integers, like 1/2? The answer is that the result rounds down to the nearest integer. Since 1/2 is 0.5, the nearest integer below that is 0, so the result is 0.
You need to use float, which uses floating point arithmetic. Floating point arithmetic has its own set of fun rounding issues (You may be surprised to find that "0.2" cannot be represented exactly with floating point numbers).
A more exact alternative is to write your own functions to handle rational numbers as a pair of integers -- a numerator and a denominator. It will require additional algorithms (such as a Greatest Common Divisor algorithm), but it can describe these sorts of problems exactly.
This question already has answers here:
Why are floating point numbers inaccurate?
(5 answers)
Closed 5 years ago.
I am a beginner and this is (a simplified version of) part of a code I am writing:
1.prompt user to input a number (float dollar amount), lets say user will only key in amount which are multiples of 0.05 ;
2.calculate the (int)number of nickels in that dollar amount.
int main(void)
{
float amount = 0;
printf("$ ");
amount = get_float();
int n = 0;
while ((amount - 0.05) >= 0)
{
amount -= 0.05;
n ++;
}
printf("%i nickels\n", n);
}
It works for any amount <=0.3 or >=1.2 (so $2 has 40 nickels, and $0.30 has 6 nickels);
but one nickel less for any amount between/including 0.35 and 1.15 (so $0.35 has 6 nickels, and $1 has 19 nickels)
I did step by step printing, and it turns out that for any amount between 0.35 and 1.15, the program stops at the last 0.050000, instead of going back to the loop and loop it one last time.
What went wrong? Please help... Thanks so much for your time!
You are hitting up against floating point rounding.
Floating points are never exactly accurate, try calculating
printf("one third 'ish' = %6.20lf\n", (double) 1.0/ (double) 3.0);
Look at the answer, it's not quite accurate. :)
Your best bet is to accept the input, convert it to an integer (ie, cents) by multiplying by 100, removing any decimals using round() and assigning to a long.
#include <math.h> // to get the round() function
.
.
.
long amountInCents = round(amount * 100);
Then, change your code to compare against 5 cents, not $0.05, and to reduce by 5 cents, not $0.05
This way, you get rid of all 'rounding' issues.
EDIT: cmaster showed me that using floor() didn't work, using $0.57 as input, when using 'double' variables (not float), $0.57 converted to (long) 56! He supplied code and I couldn't believe my eyes!
The is no bug in your code in the strictest sense as the underlying reasoning is correct; however note that the value 0.35 cannot be represented exactly in the float datatype, the same holds for 0.05; as the division (what basically is the sematics of the code in the question) is implemented via repeated subtraction, the error caused by the inability to exactly represent the desired values accumulates. The result is that the number of subtractions is different from the analytically expected result, as the termination condition is reached too soon. The float datatype is not suitable for financial calculations, even in such a very small everyday example.
This is terrible, but it is a matter of fact.
I found a fix. This is working
enter code here
while ((amount - 0.0499) >= 0)
{
amount -= 0.05;
n ++;
}
while scanning .35 amount as float the actual amount value is 0.3499
This is the code which I have written to find approx square root a non perfect number(in the order 0.0001 and also exact square root of a perfect square. It is working with non perfect square numbers but not perfect. When I put 25 it gives 5.000068
#include<stdio.h>
int main()
{
float a,i,count;
scanf("%f",&a);
for(count=1;(1);count=count+0.0001)
{
i=count*count;
if (i<=a)
break;
}
printf("%f",count);
return 0;
}
Your method is wrong for computing square roots.
You deserve a bad grade for not reading a bit about square roots. Understanding the problem is the first step for any software development.
First, you should read The Floating Point Guide and the classical What Every Programmer Should Know About Floating-Point Arithmetic. It explains why your program cannot work (i.e. gives inaccurate results).
Then, your program is very inefficient (for large input numbers like several billions, it takes an enormous amount of computing time; for very small numbers like 0.01 it probably never terminates). Learn about Newton-Raphson's method, perhaps by reading some basic math book.
Notice that many fixpoint computations translate to iterative algorithms.
There are two things that are faulty with your code:
Floating point is not exact. If you want more accuracy, use double, not float.
Your increment value is too large. If you incremented by a smaller amount you would (or should) get the desired value: See here: http://ideone.com/7XM2IK
The next issue doesn't affect your code now, but be warned anyway:
Do not use floating point arithmetic as a loop counter. To fix this issue, normalize your loop to do integer counts, and do the floating point inside the loop:
int count;
float dCount = 1.0;
float i, a;
//...
for (count=0; count < 100000; ++count)
{
//...
}
See this link: https://www.securecoding.cert.org/confluence/display/java/NUM09-J.+Do+not+use+floating-point+variables+as+loop+counters
If you dont want to struggle with books and math:
#include <stdio.h>
#include <math.h>
int main()
{
float n = 25;// ofc use scanf xD
n=sqrt(n);
printf("%.5f", n);
return 0;
}
I have a homework in C. We have to write our own asin() function with Taylor method, and we can't use math.h
It works fine, but once I put higher count of iterations(int i), it returns NaN(Not a Number), and when I use low count of i, the number is not exact. Can anyone help me with this?
double my_asin(double x)
{
int i = 0;
double vypocet = x;
double y = vypocet;
for(i=1;i<=10000;i++)
{
vypocet*=((x*x)*(2*i-1)*(2*i-1))/((2*i)*(2*i+1));
y+=vypocet;
}
printf("my_asin = %.10e\n", y);
return y;
}
EDIT: Thank you all! finished it :)
Two things are required for your answer :
Regarding maths : The series expansion you are coding is a sin inverse (arcsin) and expecting an output in radian.
sin^(-1)x=x+1/6x^3+3/(40)x^5+5/(112)x^7+(35)/(1152)x^9+... . As you can see this is an expansion which is monotonically increasing and expecting value (input) between [-1,1] only. When you plug in large values e.g. 10 you are bound to get results you don't expect.So , plug in correct values. I guess, put correct values [-1,1] when calling the function my_asin() and your code would work fine FOR THE number of ITERATIONS YOU HAVE NOW.
e.g 1.5146343691e+000 looks fine for 90 degrees or pi/2 or my_asin(1).
2 .Regarding Floating Point (double i.e. single prrecision floating point ):They cant represent all the numbers on the real line, their range is a subset of R.And when there is a number that can't be represented correctly by their 32 bits encoding (IEEE 754) you will get error in result.
Number as simple as 0.1 cant be represented exactly using floating point.
Check these pages for FP Errors and FP Exceptions :
http://www.gnu.org/software/libc/manual/html_node/Infinity-and-NaN.html
http://www.gnu.org/software/libc/manual/html_node/FP-Exceptions.html#FP-Exceptions
In my quest to learn C I've come across a task which is causing me a few problems. I need to make an equation for the approximate value of the formulae n!, which can be described as:
n! = n^n*e^(-n)*sqrt(2(2*n+1/3)*PI), however I simply cannot get my values to corrospond with the actual value. 5! = 120ish
I can get a value of some 148ish
Can't figure out where my code is wrong:
#include <stdio.h>
#include <math.h>
#define PI 3.14156
#define E_CONST 2.7828
int main ()
{
double num;
double calc, first, second, third, fourth;
printf("Give an int: ");
scanf("%lf", &num);
first = pow(num , num);
second = pow(E_CONST, -num);
third = (2 * num + 1/3);
fourth = sqrt(2*third*PI);
//calc = first * second * fourth;
calc = pow(num, num) * pow(E_CONST, -num) * sqrt(2*(2*num+(1/3))*PI);
printf("Input: %f", num);
printf("1: %.2f\n2: %.10f\n3: %.8f\n4: %.2f\n", first, second, third, fourth);
printf("\nInt was: %.2f\n\nApproximate number: %.5f", num, calc);
return 0;
}
Feel like i have tried everything. The code is a bit messy, but it's because I've scrambled so much with it now.
3.14156 is a bad value for PI: it's better to use 3.1416, or 3.14159, or 4 * atan(1), or, for POSIX implementations, M_PI.
2.7828 is a very bad value for e: it's better to use 2.7183, or exp(1), or, for POSIX implementations, M_E.
1/3 is integer division, the result is 0: it's better to use 1.0/3.
Also your approximation is incorrect. The correct approximation is
n^n * e^(-n) * sqrt((2*n+1/3)*PI)
It seems you fell into the integer division trap with 1/3, which has the value 0. You need to write this with floating point constants as 1.0 / 3.0.
You probably need to type 1.0/3.0 to get one third.