C Power function negative exponent without pow() - c

I'm trying to make a little power calculator for learning purposes in C without using pow,
but it always returns 0.00 when exponent is negative, please help.
full code:
#include<stdio.h>
//* power caculator function
int power(x,y)
{
float p=1.00;
int i;
if (y<0){
y=-1*y;
x=1/x;
}
for (i=1;i<=y;i++)
{
p=p*x;
}
return p;
}
//* main gets input, calls power caculator and prints result'
int main()
{
int b;
int e;
float p;
printf("enter base");
scanf("%d",&b);
printf("enter exponent");
scanf("%d",&e);
p=power(b,e);
printf("%d to the power of %d is %.2f",b,e,p);
return 0;
}
//* I am NOOB

You are using integers to hold decimal values, in this case with x and with the return type of the power function.
try:
float power(x,y)
{
float p=1.00;
float xx = (float)x;
int i;
if (y<0){
y=-1*y;
xx=1/xx;
}
for (i=1;i<=y;i++)
{
p=p*xx;
}
return p;
}

define data types of x and y explicitly and then adjust the return data type.

Related

can't implement any series that uses power or factorial

I wrote a program to calculate the value of e^x by series and by library function.See the following:
#include<stdio.h>
#include<math.h>
long long fact(int x)
{
long prod=1;
int i=1;
if(x==0)
return 1;
else{
while(i<=x)
{
prod=prod*i;
i++;
}
return prod;
}
}
int main()
{
int i;
float x;
double sum=1;
for(x=1;x<20;x++)
{
for(i=1;i<=10;i++)
{
if(fact(i)!=0);
sum=sum+pow(x,i)/fact(i);
}
printf("by code e=%.15lf\t\t",sum);
printf("by libfnc e=%.15f\t",exp(x));
printf("quotient =%.15f\n",sum/exp(x));
}
}
The code works for smaller values like 1,2 but with the increase of the value of x the difference (here quotient) increases.That is my code no longer gives correct answer for higher values of x.
You need function prototype before calling it.
Add some ifs to check if you do not divide by zero.
scanf returns number of successfully scanned elements. Check for 1 in this case.
int fct = fact(2*i);
if(fct)
sum=sum+y/(double)fct;
else
{printf("DIVISION BY ZERO!!!!\n"); return 1;}
You will discover that int is to small for factorial function. Change it to double. Also, use double in all floating point operations.
double fact(int x);
int main()
{
double sum,y;
int x,i=0;
double fct;
while(scanf("%d",&x) == 1)
{ sum=0;
for(i=0;i<=N;i++)
{
y=pow(-1,i)*pow(x,2*i);
fct = fact(2*i);
if(fct != 0.0)
sum=sum+y/fct;
else
{printf("DIVISION BY ZERO!!!!\n"); return 1;}
}
printf("using Maclaurin's series %.10f and original cosx=%.10f",sum,cos(x));
}
}
double fact(int x)
{
double prod=1.0;
int i=1;
for(i=1;i<=x;i++)
prod=prod*i;
return prod;
}
https://godbolt.org/z/qsh4qh3d1

EQUATION SOLVER absurd result despite correct algorithm

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
void bisect(float *p,int n,int a);
float value(float *p,int n,int a);
int main()
{
int a,i;
float *p;
printf("enter the degree of the polynomial\n");
scanf("%d",&a);
p=(float *) malloc(a*sizeof(float));
for(i=0;i<=a;i++)
{
printf("enter the coefficient of x^%d\n",i);
scanf("%f",p+i);
}
printf("%f\n",value(p,-2,a));
printf("%f\n",value(p,1,a));
printf("%f\n",value(p,0,a));
for(i=-100;i<100;i++)
{
if(value(p,i,a)*value(p,i+1,a)==0.000)
{
printf("%d\n",value(p,i+1,a));
if(value(p,i,a)==0&&value(p,i+1,a)==0.00)
{
printf("the roots are %d,%d\n",i,i+1);
}
if(value(p,i+1,a)==0.0)
{
printf("the real root is %d\n",i+1);
i++;
continue;
}
}
if(value(p,i,a)*value(p,i+1,a)<0)
{
bisect(p,i,a);
}
}
return 0;
}
float value(float *p,int n,int a)
{
float sum=0.0;
int i;
for(i=0;i<=a;i++)
{
sum=sum+*(p+i)*pow(n,i);
}
return sum;
}
void bisect(float *p,int n,int a)
{
float j,k,l;
int i;
j=n;k=n+1;l=(j+k)/2;
for(i=0;i<50;i++)
{
if(value(p,j,a)*value(p,l,a)==0){break;}
if(value(p,j,a)*value(p,l,a)<0)
{
j=j;k=l;l=(j+k)/2;
}
else if(value(p,l,a)*value(p,k,a)<0)
{
l=(l+k)/2;j=l;
}
}
printf("the root of the equation is %f\n",l);
}
I tried inserting print statements in the main function, and found that the value function is giving absurd results for simple polynomials, but the roots are correct for some polynomials but wrong for many. Why would the roots be correct for some if the algorithm was wrong?
There are so many problems in your code:
In main method,
printf("%d\n",value(p,-2,a));
Compiler should give you warning:
warning: format '%d' expects argument of type 'int', but argument 2 has type 'double'
Use %f instead of %d as value() returns float.
You are not allocating enough space and you are casting the return value of malloc. Casting the return value of malloc should be avoided since malloc returns a void * (which means that it needs no cast) and casting the return value can conceal errors. You can read more about this issue here.
p = (float *) malloc(a*sizeof(float));
to
p=malloc((a+1) * sizeof *p);
You are comparing floating ponit number here:
if(value(p,i,a)==0&&value(p,i+1,a)==0.00)
Don't do this, read What Every Computer Scientist Should Know About Floating-Point Arithmetic for the reason. You can use one of this (e.g nearlyEqual()) functions for your purpose.
In method bisect():
j=j;k=l;l=(j+k)/2; // j = j, kidding?
The biggest conceptual or mathematical error (apart from the programming errors explained in the other answer) is that you use integers for the arguments in the value function. It is rarely the case that random polynomials have integer roots. Rename n to x for intuitive readability and set the type of x to float.
Check again your assignment, if the prototype is really value(p,n,a), then maybe the intention is that n is the degree and a the evalution point, thus the signature should be (*float,int,float).
Using this signature, you should really use the Horner scheme to evaluate densely coded polynomials
float value(float *p, int deg, float a) {
int i;
float val = p[deg];
for(i=deg; i-- > 0; ) val = val*a+p[i];
return val;
}
and use descriptive names for variables in the bisection method (instead of j,k,l usually associated to integers) to avoid mixing them up
float left=a, right = a+1, mid =(left+right)/2;
etc.

What does #QNANO signify or mean in C?

#include<stdio.h>
#include<math.h>
int n;
struct vector
{
int dir[100];
};
int dot(struct vector v1, struct vector v2)
{
int dp,j;
dp=0;
for(j=0;j<n;j++)
{
dp = dp + (v1.dir[j]*v2.dir[j]);
}
return dp;
}
float cosine(int vdot, float v1mod, float v2mod)
{
float cos1, vdo = vdot;
cos1 = (vdot/(v1mod*v2mod));
return cos1;
}
float modul(struct vector v1)
{
int j;
float v1mod;
float deg = 0;
for(j=0; j<n; j++)
{
deg = deg + ((v1.dir[j])*(v1.dir[j]));
}
v1mod = sqrt(deg);
}
int main()
{
int j;
scanf("%d", &n);
struct vector v1;
struct vector v2;
for(j=0;j<n;j++)
{
scanf("%d", &v1.dir[j]);
}
for(j=0;j<n;j++)
{
printf("%d/", v1.dir[j]);
}
printf("\n");
for(j=0;j<n;j++)
{
scanf("%d", &v2.dir[j]);
}
for(j=0;j<n;j++)
{
printf("%d/", v2.dir[j]);
}
printf("\n");
int vdot;
float v1mod, v2mod, cos2;
vdot = dot(v1,v2);
printf("%d\n", vdot);
v1mod = modul(v1);
printf("%f\n", v1mod);
v2mod = modul(v2);
printf("%f\n", v2mod);
cos2 = cosine(vdot, v1mod, v2mod);
printf("cosine = %f\n", cos2);
}
When we compile the code, the output for cosine is showing "1.#QNANO.
I checked all the websites, but no where did I find the right reason for the occurrence of the
error.
Also can some one specify how many such more error types are there .
**The bug in the code is intentional.
The Q probably means it's a quiet not-a-number. The O might mean overflow.
What exact platform and compiler did you use?
So I was running a few codes and doing some experiments and came across this Error. (#QNANO)
The most valid explanation I could come up with is the data specifier mismatch i.e have a look at this simple code:
#include<stdio.h>
int main()
{
int a,c;
a = 2;
float b;
b = 3;
c = a*b;
printf("%f",c);
return 0;
}
The output of this simple code is -1 #QNANO, so I assume that as an integer variable was multiplied by a floating variable and the result was stored in an integer variable but when we print the value of c and we do that with %f, then the integer variable cannot be converted to float and hence the error throws up.

returning a floating point value from a function

hey i really need help with this program.. i doesnt want return a proper answer for a negative power always return 1.. can anyone help??
The program should help the user to enter a base number and power and when executed calculates the value and displays the result
float square (float a,int b);
int main(){
int power;
float base;
printf("Please input your base number :\n");
scanf("%f",&base);
printf("Please input your power :\n");
scanf("%d",&power);
float answer = square(base,power);
printf("Your Result is :\n%f\n",answer);
system("pause");
return 0;
}
float square (float a,int b){
int counter;
float total = 1;
if (b==0){
return 1;
} else if (b>0){
for(counter=0;counter<b;counter++){
total = total*a;
}
return total;
} else {
for (counter=0;counter<b;counter++){
total = total*a;
}
total = 1 / total;
return total;
}
}
Declare total as a float instead of an int.
Also, your if's should be on b instead of a.
After that, remove all those unnecessary (float) castings.
Also, your last for for should run backwards as your initial value is less than 0.
Your square function should look like this:
float square (float a,int b){
int counter;
float total = 1;
if (b==0){
return 1;
} else if (b>0){
for(counter=0;counter<b;counter++){
total = (float)total*a;
}
return total;
} else {
for (counter=0;counter< -b;counter++){
total = (float)total*a;
}
total = 1.0 / (float)total;
return total;
}
}
You need a float for total, you need to check b instead of a in your if statements, and you need to count up to -b when it's negative.
Declare total to float and initialize it as
float total = 1.0f;
Use abs function for dealing with -ve b.
else {
for (counter=0;counter < abs(b);counter++){
total = total*a;
}
total = 1 / total;
return total;
}
and include <stdlib.h>.
See the working code Here.
This part
} else {
for (counter=0;counter<b;counter++){
total = total*a;
}
total = 1 / total;
return total;
}
ignores the fact that b is < 0.
So either you should put b = -b; in, or
for (counter=0;counter>b;counter--){
total = total / a;
}
return total;
might help you.
This does the job ;)
#include <stdio.h>
#include <math.h>
int main(){
int power;
float base;
printf("Please input your base number :\n");
scanf("%f",&base);
printf("Please input your power :\n");
scanf("%d",&power);
float answer = pow(base,power);
printf("Your Result is :\n%f\n",answer);
system("pause");
return 0;
}
Here's a cool trick:
y = a^b
ln(y) = b ln(a)
y = exp(b ln(a))
so the function should look like this:
double Power(double a, double b)
{
return exp(b*log(a));
}

-1.#IND00 output for certain input values

I'm trying to write a code that will take x as input and give cos(x) as output, using maclaurin's series.I'm using a while loop until the difference of two consecutive results is less then 0.001. I'm using double type to accomodate larger values.
the code works when x is in range [-2,2], but if x is greater or less than this range the ouput is -1.#IND00. Why is it happening? is the output value out of range ? how can i fix this ??
my code is :
#include <stdio.h>
double abs(double a);
double power(double p, int q);
int fact(int a);
int main()
{
int i=1,j=2*i;
double x,s=1.0,p,l=0.001;
printf("Enter x: ");
scanf("%lf", &x);
p = s+ power(-1,i) * power(x,j) / fact(j);
while (abs(p-s)>l){
i++; j=2*i;
s=p;
p = s+ power(-1,i) * power(x,j) / fact(j);
}
printf("cos(%f) = %f", x,p);
return 0;
}
double abs(double a)
{
if (a>=0) return a;
else return (-a);
}
double power(double p, int q)
{
int i;
double a=1.0;
for (i=0; i<q; i++){
a=a*p;
}
return a;
}
int fact(int a)
{
int i,p=1;
if (a==0 || a==1) return 1;
else
while (a!=1){
p=p*a;
a--;
}
return p;
}
update your scanf function to
scanf("%lf", &x);
Also you need to check pow and fact, these functions could overflow. Especially, fact which only use int.
As a larger |x| is use, more terms are needed and fact() overflows and strange results follow. Use double.
// int fact(int a)
double myfact(double p, int q) {
int i;
double a = 1.0;
for (i=0; i<q; i++){
a=a*p;
}
return a;
}
Eventually with values somewhere larger |x| > 30, other limitations kick in using this method. The limitation is due to precision and not range. For large values a significantly different algorithm should be used.
Potential conflict between int abs(int j) in <stdlib.h>. The prototyped may be found via stdio.h and conflicts with OP double abs(double a). In any case, abs() is a standard library function and OP should avoid that function name. Also recommend renaming power().
// double abs(double a)
double myabs(double a)

Resources