the value it give is 557135813.94455. does the value will remain same every time?? why its not showing infinity??
#include <stdio.h>
#include <math.h>
#define PI 3.14159265
int main ()
{
double param, result;
param = 90.0;
result = tan ( param * PI / 180.0 );
printf ("The tangent of %f degrees is %f.\n", param, result );
return 0;
}
You are not passing the value of Pi/2, you are passing 90.0 * 3.14159265 / 180.0, an approximation.
Code is not asking for the tangent of 90°, but the tangent of a number, in radians, close to 90°. The conversion to radians is not exact since π/2 radians is not representable exactly as a double.
The solution is to perform degrees range reduction first and then call tan(d2r(x)).
#include <math.h>
static double d2r(double d) {
return (d / 180.0) * ((double) M_PI);
}
double tand(double x /* degrees */) {
if (!isfinite(x)) {
return tan(x);
} else if (x < 0.0) {
return -tand(-x);
}
int quo;
double x45 = remquo(fabs(x), 90.0, &quo);
//printf("%d %f ", quo & 3, x45);
switch (quo % 4) {
case 0:
return tan(d2r(x45));
case 1:
return 1.0 / tan(d2r(- x45));
case 2:
return -tan(d2r(-x45));
case 3:
return -1.0 / tan(d2r(x45));
}
return 0.0;
}
#define PI 3.14159265
int main(void) {
double param, result;
param = 90.0;
result = tan(param * PI / 180.0);
printf("Angle %.*e radian\n", DBL_DECIMAL_DIG - 1, param * PI / 180.0);
printf("Pi/2 = 1.5707963267948966192313216916398...\n");
printf("The tangent of %f degrees is %f.\n", param, result);
int i;
for (i = -360; i <= 360; i += 30) {
printf("The tangent method 1 of %.1f degrees is %.*e\n",
1.0*i, DBL_DECIMAL_DIG - 1, tan(d2r(-i)));
printf("The tangent method 2 of %.1f degrees is %.*e\n",
1.0*i, DBL_DECIMAL_DIG - 1, tand(-i));
}
return 0;
}
OP's output
Angle 1.5707963250000001e+00 radian
Pi/2 = 1.5707963267948966192313216916398...
The tangent of 90.000000 degrees is 557135183.943528.
Better results
The tangent method 1 of -360.0 degrees is -2.4492935982947064e-16
The tangent method 2 of -360.0 degrees is 0.0000000000000000e+00
The tangent method 1 of -330.0 degrees is -5.7735026918962640e-01
The tangent method 2 of -330.0 degrees is -5.7735026918962573e-01
The tangent method 1 of -300.0 degrees is -1.7320508075688770e+00
The tangent method 2 of -300.0 degrees is -1.7320508075688774e+00
The tangent method 1 of -270.0 degrees is 5.4437464510651230e+15
The tangent method 2 of -270.0 degrees is -inf
The tangent method 1 of -240.0 degrees is 1.7320508075688752e+00
The tangent method 2 of -240.0 degrees is 1.7320508075688774e+00
The tangent method 1 of -210.0 degrees is 5.7735026918962540e-01
The tangent method 2 of -210.0 degrees is 5.7735026918962573e-01
The tangent method 1 of -180.0 degrees is -1.2246467991473532e-16
The tangent method 2 of -180.0 degrees is 0.0000000000000000e+00
...
Floating point arithmetic is not an exact arithmetic. You cannot even compare two floating point numbers using ==; e.g. 0.6 / 0.2 - 3 == 0 should be true but on most systems it will be false. Be careful when you perform floating point calculations and expect exact results; this is doomed to fail. Consider every floating point calculation to only return an approximation; albeit a very good one, sometimes even an exact one, just don't rely on it to be exact.
Related
This was a homework problem to find cosine of an angle without using the inbuilt cos function
I wrote the following code:
// Program to find cos x using loop.
#include <stdio.h>
#define _USE_MATH_DEFINES
#include <math.h>
double cosine(double);
int main()
{
double x;
printf("Enter angle in degrees: ");
scanf("%lf", &x);
x = x*M_PI/180.0;
printf("The value of cos(%lf) is %lf", x, cosine(x));
}
double cosine(double x)
{
double previous, current = 1;
double denominator = 1*2, numerator = x*x;
double sign = -1;
while(1)
{
previous = current;
current = current + ((numerator)/(denominator))*sign;
denominator = denominator * (denominator+1) * (denominator+2);
numerator = numerator*x*x;
sign = -sign;
if (fabs(previous - current)<=0.0001)
{
break;
}
}
return current;
}
For x = 180 the answer isn't -1 (which is the correct one)
I have no clue what is going wrong here. Please help I am relatively new at programming.
I tested out your code and found an error in the derivation of the factorial value for your denominator. The following line of code was actually not providing a proper factorial value.
denominator = denominator * (denominator+1) * (denominator+2);
It actually was increasing the denominator value too fast.
With that in mind, I did a bit of refactoring including revising the "while" loop test for previous and current to a simple "for" loop with enough iterations to provide the precision you most likely need. Following is a refactored version of your program.
// Program to find cos x using loop.
#include <stdio.h>
#define _USE_MATH_DEFINES
#include <math.h>
double cosine(double);
int main()
{
double x;
printf("Enter angle in degrees: ");
scanf("%lf", &x);
x = x * M_PI / 180.0;
printf("The value of cos(%lf) is %lf\n", x, cosine(x));
}
double cosine(double x)
{
double current = 1.00;
double denominator = 2.00, numerator = x*x;
double factor = 2.00;
double sign = -1;
for(int i = 0; i < 16; i++)
{
current = current + ((numerator)/(denominator))*sign;
denominator = denominator * (factor+1.00) * (factor+2.00); /* Derives the proper factorial increase */
numerator = numerator * x * x;
sign = -sign;
factor = factor + 2.00;
}
return current;
}
Some points to note.
Instead of the previous formula for calculating the needed factorial, a work field for keeping track of the ascending factorial values is added and incremented as needed and utilized in the denominator calculation.
Instead of testing for smaller and smaller differences with the "while" loop, a "for" loop is utilized with enough iterations to provide a desired precision for the cosine value.
With those tweaks, following were some tests listed at the terminal.
#Vera:~/C_Programs/Console/Taylor/bin/Release$ ./Taylor
Enter angle in degrees: 0
The value of cos(0.000000) is 1.000000
#Vera:~/C_Programs/Console/Taylor/bin/Release$ ./Taylor
Enter angle in degrees: 90
The value of cos(1.570796) is 0.000000
#Vera:~/C_Programs/Console/Taylor/bin/Release$ ./Taylor
Enter angle in degrees: 180
The value of cos(3.141593) is -1.000000
#Vera:~/C_Programs/Console/Taylor/bin/Release$ ./Taylor
Enter angle in degrees: 270
The value of cos(4.712389) is 0.000000
#Vera:~/C_Programs/Console/Taylor/bin/Release$ ./Taylor
Enter angle in degrees: 360
The value of cos(6.283185) is 1.000000
Give those tweaks a try and see if it meets the spirit of your project.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have an exercise that tell me these:
Functions
Problem 1
Function floor may be used to round a number to a specific decimal place. The statement
y = floor( x * 10 + .5 ) / 10;
rounds x to the tenths position (the first position to the right of the decimal point). The
statement
y = floor( x * 100 + .5 ) / 100;
rounds x to the hundredths position (the second position to the right of the decimal
point).
Write a program that defines four functions to round a number x in various ways
a. roundToInteger( number )
b. roundToTenths( number )
c. roundToHundreths( number )
d. roundToThousandths( number )
For each value read, your program should print the original value, the number rounded to
the nearest integer, the number rounded to the nearest tenth, the number rounded to
the nearest hundredth, and the number rounded to the nearest thousandth.
Input Format
Input line contain a float number.
Output Format
Print the original value, the number rounded to the nearest integer, the number rounded
to the nearest tenth, the number rounded to the nearest hundredth, and the number
rounded to the nearest thousandth
Example:
Input
24567.8
Output
24567.8 24568 24570 24600
My solution (which is wrong) is:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double roundToInteger(double number)
{
double roundedNum;
roundedNum = floor(number + .5);
return roundedNum;
}
double roundToTenths(double number)
{
double roundedNum;
roundedNum = floor(number * 10.0 + .5) / 10.0;
return roundedNum;
}
double roundToHundreths(double number)
{
double roundedNum;
roundedNum = floor(number * 100.0 + .5) / 100.0;
return roundedNum;
}
double roundToThousandths(double number)
{
double roundedNum;
roundedNum = floor(number * 1000.0 + .5) / 1000.0;
return roundedNum;
}
int main()
{
double userInput = 0.0, userInput1 = 0.0, userInput2 = 0.0,userInput3 = 0.0, userInput4 = 0.0, originalVal = 0.0;
printf("Enter a double value: ");
scanf("%lf", &userInput);
originalVal = userInput;
userInput1 = roundToInteger(userInput);
userInput2 = roundToTenths(userInput);
userInput3 = roundToHundreths(userInput);
userInput4 = roundToThousandths(userInput);
printf("%lf %lf %lf %lf %lf", originalVal, userInput1,userInput2,userInput3, userInput4);
}
What in the formula I am doing wrong?
If the input is 24567.8 and the expected output is 24567.8 24568 24570 24600, change your formulas from:
y = floor( x * 10...0 + .5 ) / 10...0;
To:
y = floor( x / 10...0 + .5 ) * 10...0;
In other words, you implemented correctly the formulas provided. Only thing wrong here is the fact the formulas are wrong for rounding powers of ten. Those are for rounding decimal places.
As part of a exercise from "The C programming Language" i am trying to find a way to calculate the maximum possible float and the maximum possible double on my computer. The technique shown below works with floats (to calculate the max float) but not with double:
// max float:
float f = 1.0;
float last_f;
float step = 9.0;
while(1) {
last_f = f;
f *= (1.0 + step);
while (f == INFINITY) {
step /= 2.0;
f = last_f * (1.0 + step);
}
if (! (f > last_f) )
break;
}
printf("calculated float max : %e\n", last_f);
printf("limits.h float max : %e\n", FLT_MAX);
printf("diff : %e\n", FLT_MAX - last_f);
printf("The expected value? : %s\n\n", (FLT_MAX == last_f)? "yes":"no");
// max double:
double d = 1.0;
double last_d;
double step_d = 9.0;
while(1) {
last_d = d;
d *= (1.0 + step_d);
while (d == INFINITY) {
step_d /= 2.0;
d = last_d * (1.0 + step_d);
}
if (! (d > last_d) )
break;
}
printf("calculated double max: %e\n", last_d);
printf("limits.h double max : %e\n", DBL_MAX);
printf("diff : %e\n", DBL_MAX - last_d);
printf("The expected value? : %s\n\n", (DBL_MAX == last_d)? "yes":"no");
and this results to:
calculated float max : 3.402823e+38
limits.h float max : 3.402823e+38
diff : 0.000000e+00
The expected value? : yes
calculated double max: 1.797693e+308
limits.h double max : 1.797693e+308
diff : 1.995840e+292
The expected value? : no
It looks to me like it still calculates using single precision in the second case.
What am i missing?
OP's approach works when calculations are done with wider precision than float in the first case and wider than double in the 2nd case.
In the first case, OP reports FLT_EVAL_METHOD == 0 so float calculations are done as float and double are done as double. Note that float step ... 1.0 + step is a double calculation.
The below code forces the calculation to double and so I can replicate OP's problem even with my FLT_EVEL_METHOD==2 (Use long double for internal calculations.)
volatile double d = 1.0;
volatile double last_d;
volatile double step_d = 9.0;
while(1) {
last_d = d;
d *= (1.0 + step_d);
while (d == INFINITY) {
step_d /= 2.0;
volatile double sum = 1.0 + step_d;
d = last_d * sum;
//d = last_d + step_d*last_d;
}
if (! (d > last_d) ) {
break;
}
}
diff : 1.995840e+292
The expected value? : no
Instead OP should use the following which does not form the inexact sum of 1.0 + step_d when step_d is small, rather it forms the exact product of step_d*last_d. The 2nd form results in a more accurate calculation for the new d, by providing an additional bit of calculation precision in d. Higher precision FP is not needed to employ OP's approach.
d = last_d + step_d*last_d;
diff : 0x0p+0 0.000000e+00
The expected value? : yes
The expressions with the literals n.0 are all double precision floating point types. That allows the assignment to f to be calculated using a higher precision intermediate value.
It's this effect that allows the algorithm to converge in the float case.
With strict double precision floating point such convergence is not possible.
If you had used the f suffix on the literals in the float case then convergence would not occur there either.
A fix would be to use long double suffixes on the literals if your platform has a wider long double type.
I am trying to compute the square root of a number using function containing a while loop. Within the conditions of the while loop, I want to compare the absolute value of the ratio of the two values, the guessed square root and the number, to 1. However, whenever I run the program, I keep get an infinite loop outputting 1.414214. Any help? Thanks.
// Function to calculate the absolute value of a number
#include <stdio.h>
float absoluteValue (float x)
{
if ( x < 0 )
x = -x;
return (x);
}
// Function to compute the square root of a number
float squareRoot (float x, const float epsilon)
{
float guess = 1.0;
while ( absoluteValue ((guess * guess) / x) != epsilon ) {
guess = ( (x / guess) + guess ) / 2.0;
printf("%f\n", guess);
}
return guess;
}
int main (void)
{
printf ("squareRoot (2.0) = %f\n", squareRoot (2.0, 1.0));
printf ("squareRoot (144.0) = %f\n", squareRoot (144.0, 1.0));
printf ("squareRoot (17.5) = %f\n", squareRoot (17.5, 1.0));
return 0;
}
Change this:
while ( absoluteValue ((guess * guess) / x) != epsilon ) {
To:
while ( absoluteValue ((guess * guess) / x - 1.0) > epsilon ) {
You want to keep refining your answer until it's within epsilon of the goal. You need to subtract 1.0 from the ratio, to get the difference between what you're seeing and your goal, then you want to stop once the difference is within epsilon. You don't want to keep trying if it's smaller than epsilon.
You will also want to use much smaller values for epsilon, e.g. 0.000001
In real world cube root for a negative number should exist:
cuberoot(-1)=-1, that means (-1)*(-1)*(-1)=-1
or
cuberoot(-27)=-3, that means (-3)*(-3)*(-3)=-27
But when I calculate cube root of a negative number in C using pow function, I get nan (not a number)
double cuber;
cuber=pow((-27.),(1./3.));
printf("cuber=%f\n",cuber);
output: cuber=nan
Is there any way to calculate cube root of a negative number in C?
7.12.7.1 The cbrt functions
Synopsis
#include <math.h>
double cbrt(double x);
float cbrtf(float x);
long double cbrtl(long double x);
Description
The cbrt functions compute the real cube root of x.
If you're curious, pow can't be used to compute cube roots because one-third is not expressible as a floating-point number. You're actually asking pow to raise -27.0 to a rational power very nearly equal to 1/3; there is no real result that would be appropriate.
there is. Remember: x^(1/3) = -(-x)^(1/3). So the following should do it:
double cubeRoot(double d) {
if (d < 0.0) {
return -cubeRoot(-d);
}
else {
return pow(d,1.0/3.0);
}
}
Written without compiling, so there may be syntax errors.
Greetings,
Jost
As Stephen Canon answered, to correct function to use in this case is cbrt(). If you don't know the exponent beforehand, you can look into the cpow() function.
#include <stdio.h>
#include <math.h>
#include <complex.h>
int main(void)
{
printf("cube root cbrt: %g\n", cbrt(-27.));
printf("cube root pow: %g\n", pow(-27., 1./3.));
double complex a, b, c;
a = -27.;
b = 1. / 3;
c = cpow(a, b);
printf("cube root cpow: (%g, %g), abs: %g\n", creal(c), cimag(c), cabs(c));
return 0;
}
prints
cube root cbrt: -3
cube root pow: -nan
cube root cpow: (1.5, 2.59808), abs: 3
Keep in mind the definition of the complex power: cpow(a, b) = cexp(b* clog(a)).
Using Newton's Method:
def cubicroot(num):
flag = 1
if num < 0:
flag = -1
num = num - num - num
x0 = num / 2.
x1 = x0 - (((x0 * x0 * x0) - num) / (3. * x0 * x0))
while(round(x0) != round(x1)):
x0 = x1
x1 = x0 - (((x0 * x0 * x0) - num) / (3. * x0 * x0))
return x1 * flag
print cubicroot(27)