Using while loops instead of pow: What does this error mean? - c

I am attempting to create some code with C programming that can show a number to a certain power with both values specified by the user. I want to use pow for the first part and a while loop for the second. However, I've confronted an error with this current code that I cannot seem to get rid of.
Here is ther error that I am unfamiliar with:
error: invalid operands to binary * (have ‘int (*)(int, int)’ and ‘int’)
result2 = result2 * base;
I've tried looking into other questions with the same error, but they differ so much that I cannot understand.
I've tried researching into "long" but I have not been experienced with it yet through my C textbook, so I would like to refrain from using it if possible.
#include <stdio.h>
#include <math.h>
int result2(int base, int exponent);
int main(void)
{
double base;
double exponent;
double result1;
puts("Please enter a value as the base and another as the exponent.");
scanf("%lf%lf", &base, &exponent);
result1 = pow(base, exponent);
printf("Library solution: %lf\n", result1);
printf("My solution: %d\n", result2(base, exponent));
}
int result2(int base, int exponent)
{
int i;
for(i=1; i<=exponent; i++)
{
result2 = result2 * base;
}
return;
}
I would like to be able to calculate the equation properly using both methods with the user's values. However, with this error, I just cannot seem to get past and achieve that. Thank you.

int result2(int base, int exponent)
{
int i;
for(i=1; i<=exponent; i++)
{
result2 = result2 * base;
}
return;
}
result2 is the name of your function. Rather than using it like a variable that can accumulate the results of the loop, you should create a variable to do that job. Then return the value of the variable at the end.
int result2(int base, int exponent)
{
int i;
int result = 1;
for(i=1; i<=exponent; i++)
{
result = result * base;
}
return result;
}
Better yet, give the function a different name. result2 sounds like the name of a variable. The function should be named something that indicates what it does. Since pow is taken, how about power?
int power(int base, int exponent)
{
int result = 1;
for (int i=1; i<=exponent; i++)
{
result *= base;
}
return result;
}
Some other small improvements are declaring int i inside the for loop, and using result *= base as shorthand for result = result * base.

i made a few modifications to your code.
1) Renamed funtion result2 to my_exp. result2 sound like a variable.
2) Modify types for funtion my_exp to int to be consistent with the variables types of main.
3) Add a variable result in my_exp to store the partial result of for loop.
4) Declared i inside for declaration.
5) call pow and my_exp inside printf and remove result1 is not necesary anymore.
6) Changed how result is calculed to a more compact way.
most of those changes are cosmetic except for types changes.
int my_exp(int base, int exponent);
int main(void)
{
int base;
int exponent;
puts("Please enter a value as the base and another as the exponent.");
scanf("%i", &base);
scanf("%i", &exponent);
printf("Library solution: %i\n", pow(base, exponent));
printf("My solution: %i\n", my_exp(base, exponent));
}
int my_exp(int base, int exponent)
{
//int i;
int result;
result = 1;
for(int i=1; i<=exponent; i++)
{
result *= base;
}
return result;
}

Related

why does the value of this factorial change when called by a function that SHOULD calculate the value of e

#include <stdio.h>
#include <math.h>
int main()
{
double precision = 0;
printf("\ninsert number\n");
while(precision < 1){
scanf("%lf",&precision);
}
printf("the value of e with precision of %.0lf is %lf",precision,e(precision));
return 0;
}
int fact(int num){
int ris = 1;
for(int i = num;i > 0;i--){
ris = ris * i;
}
printf("res=%d\n",ris);
return ris;
}
int e(double precision){
double valE = 1;
for(double i = precision;i > 0 ;i--){
valE = valE + 1/fact(i);
printf("\nsame res:%.1lf\n",fact(i));
}
return (double)valE;
}
debug
i know there is an answer for that but my problem is the comunication between the 2 functions, i know i could solve it by slapping everything inside the main()
There are many issues:
format specifiers (for scanf and printf) must match the arguments
don't use floating point types as counters
if you divide one integer by another integer, the result will be an integer that is trucated. If you want the result to be a floating point type, you need to convert at least one of the operands to a floating point type.
you need to declare the functions you use (fact and e) before using them, or just put them before main, like below.
You want this, explanations in the comments:
#include <stdio.h>
#include <math.h>
int fact(int num) {
int ris = 1;
for (int i = num; i > 0; i--) {
ris = ris * i;
}
printf("res=%d\n", ris);
return ris;
}
double e(int precision) {
double valE = 1;
for (int i = precision; i > 0; i--) { // use int for loop counters
valE = valE + 1.0 / fact(i); // use `1.0` instead of `1`, otherwise an
// integer division will be performed
printf("\nsame res: %d\n", fact(i)); // use %d for int^, not %llf
}
return valE; // (double) cast is useless
}
// put both functions e and fact before main, so they are no longer
// declared implicitely
int main()
{
int precision = 0; // precision should be an int
printf("\ninsert number\n");
while (precision < 1) {
scanf("%d", &precision); // use %d for int
}
printf("the value of e with precision of %d is %lf", precision, e(precision));
return 0;
}

Write a C function to evaluate the series // sin(x) = x-(x3 /3!)+(x5 /5!)-(x7 /7!)+... // up to 10 terms

#include <stdio.h>
#include<math.h>
int series(float,float);
int main()
{
float x,n,series_value;
printf("Enter the value of x: ");
scanf("%f",&x);
printf("\nEnter the value of n: ");
scanf("%f",&n);
series_value=series(x,n);
printf("\nValue of series sin (%.2f) is: %f\n",x,series_value);
return 0;
}
int series(float x,float n)
{
int i,sum=0,sign=-1;
int j,fact=1,p=1;
for (i=1; i<=(2*n)-1; i+=2)
{
for (j=1; j<=i; j++)
{
p=p*x;
fact=fact*j;
}
sign=-1*sign;
sum=sum + sign*p/fact;
}
return (sum);
}
Output:
Enter the value of x: 5
Enter the value of n: 10
(lldb)
and this message
Thread 1: EXC_ARITHMETIC (code=EXC_I386_DIV, subcode=0x0)
![Thread 1 Queue : com.apple.main-thread (serial)
]1
Why is this message coming? and what is wrong in the program as answer is not coming right
There is a few problems with your code. As #PaulHankin said, when fact overflows and becoms zero, you will have a division by zero, and "weird things" happen.
Your factorial and power calculation is also wrong. You are recalculating it in each iteration of the outer loop without reseting fact and p first:
fact = 1; // You need to reset fact and p to its start value here
p = 1;
for (j=1; j<=i; j++)
{
p=p*x;
fact=fact*j;
}
Your third problem is that for your function calculate the correct value for sin, which is not an integer value, you need to use float, or even better double, when calculating sum. So sum must be declared float, and the division p/fact must use float division. By also declaring p and fact as float, you will solve both the overflow issue, and use the correct division. Naturally your function must also return a float
float series(float x,float n)
{
int i,sign=-1;
int j,
float sum = 0;
float fact = 1;
float p = 1;
for (i=1; i<=(2*n)-1; i+=2)
{
fact = 1;
p = 1;
for (j=1; j<=i; j++)
{
p=p*x;
fact=fact*j;
}
sign=-1*sign;
sum=sum + sign*p/fact;
}
return (sum);
}
This code still has a minor problem. By having an inner loop, it is slower than necessary. Since this probably is homework, I am not getting rid of that loop for you, just giving you a hint: You don't have to recalculate fact from scratch on each iteration of the outer loop, just try to find out how fact changes from one iteration to the next. The same goes for p.
//Series of Sinx
#include<stdio.h>
#include<math.h>
#define ACCURACY 0.0001
int factorial(int n);
int main()
{
float x,sum,term;
int i,power;
printf("Enter value of X: ");
scanf("%f",&x);
i=1;
power=3;
sum=x;
term=x;
while(term>=ACCURACY)
{
term = pow(x,power) / factorial(power);
if(i%2==1)
{
sum -= term;
}
else
{
sum += term;
}
power+=2;
i++;
}
printf("sin(%f) = %.6f\n",x,sum);
return 0;
}
int factorial(int n){
int i=n,fact=1;
for(i=1;i<=n;i++)
{
fact=fact*i;
}
return fact;
}
plenty bugs. To do not caclulate the fact values all the time they are in the lookup table
#include <stdio.h>
#include <math.h>
double series(double,int);
long long fact[] = { 1, 2, 6, 24,
120, 720, 5040, 40320,
362880, 3628800, 39916800, 479001600,
6227020800, 87178291200, };
double mypow(double x, unsigned p)
{
double result = x;
while(p && --p)
result *= x;
return result;
}
int main()
{
for(double x = 0; x <= M_PI + M_PI / 60; x += M_PI / 30)
printf("Value of series sin (%.2f) is: %f\n",x,series(x, 5));
fflush(stdout);
}
double series(double x,int n)
{
double sum = x;
int i,sign=1;
for (i=3; i<=(2*n)-1; i+=2)
{
sign=-1*sign;
sum += sign*(mypow(x, i)/fact[i -1]);
}
return (sum);
}
https://godbolt.org/z/U6dULN
maybe its due to floating-point exception as u have declared that the function should return int type value
int series(float,float);//hear
so u can try editing the return type of this function as float
Note:-also u need to change at function definition and the datatype of
int i,sum=0,sign=-1;
int j,fact=1,p=1;
to float as it is returning the value (sum) which should also be float

Return values does not work in printf() formatting

The problem here is when I try to print the result as in the following code, this will give an output as "0 is the result."; however, when I assign pow(5,3) to a variable x then write printf("%d is the result.\n",x); it prints the correct result. Why is this happening?
#include <stdio.h>
int power(int base, int exp) {
int result = 1;
int i;
for (i = 0; i < exp; i++) {
result *= base;
}
return result;
}
int main() {
printf("%d is the result.\n", power(5,3));
return 0;
}
It works for me when I try your program. But pow is a library function from the math library, returning double, and the name is reserved. Try to rename it to something like my_pow.

Function is returning garbage value

I have the following code in C :
#include <stdio.h>
// Global variables :
int i;
int x[10];
int Nmax;
int sum;
// Functions used :
void Summation();
int Average(float avg); // This function will return avg
int main()
{
float avg;
printf("Mention how many numbers to be added\n");
scanf("%d",&Nmax);
printf("Enter %d numbers\n",Nmax);
for (i=0; i<Nmax; i++){
scanf("%d",&x[i]);
}
Summation();
Average(avg);
printf("%d %d %f\n",Nmax,sum,avg);
printf("Average = %.2f\n",avg);
return 0;
}
// Summation :
void Summation()
{
sum=0;
for (i=0; i<Nmax; i++) {
sum=sum+x[i];
}
printf("Sum of them = %d\n",sum);
}
// Average
int Average(float avg)
{
avg=(float)sum/(float)Nmax;
return avg;
}
Somehow the function Average is not returning the expected average value.
Instead it's showing a garbage value.
A typical input/output :
Mention how many numbers to be added
4
Enter 4 numbers
1 2 3 4
Sum of them = 10
4 10 1637156136366093893632.000000
Average = 1637156136366093893632.00
What's going wrong here? Hope I don't require a pointer here or do I?
For the average function you are passing the argument as pass by value. Once you call the function your are not assigning the return value back to the avg variable inside the main function. So what you are printing is the garbage value inside the avg variable declared in main function. Change your code to
avg = Average(avg);
Also this is a very bad way of writing c programs. Please dont you use global variables if you dont need them.
You are mixing int and float and that can cause problems.
You are never initializing avg in main(), use parameters instead of global variables to avoid the confusion. You pass avg's value to Average() it has absolutely no use in this case.
In c parameters to functions are always passed by value so the value of avg is not being modified in Average(), you may think it is because you seem confused about how you can modify global variables everywhere. The truth is global variables are mean, of course they have their uses for example, a global state in a library could be stored in a global variable1 but generally they are not needed.
Try like this
#include <stdio.h>
// Functions used :
float Summation(float *data, int size);
float Average(float *data, int size); // This function will return avg
int
main(void)
{
int size;
printf("Mention how many numbers to be added\n");
if (scanf("%d", &size) == 1)
{
float data[size];
float sum;
float average;
int i;
printf("Enter %d numbers\n", size);
for (i = 0 ; ((i < size) && (scanf("%f", &data[i]) == 1)) ; i++)
;
size = i;
sum = Summation(data, size);
average = Average(data, size);
printf("%d %f %f\n", size, sum, average);
printf("Average = %.2f\n", average);
}
return 0;
}
// Summation :
float
Summation(float *data, int size)
{
float sum;
sum = 0;
for (int i = 0 ; i < size ; i++)
sum = sum + data[i];
return sum;
}
// Average
float
Average(float *data, int size)
{
return Summation(data, size) / (float) size;
}
Note that you "don't really need an Average() function.", although it could be useful to make the API clean.
1Although I don't like that either, it makes the library very limited in multithreaded environments. Still sometimes it makes senes, but you can always have a structure with all the needed data and pass it in every call to the library API. So global variables are very rarely good.

-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