I want to avoid 'floating point error' in C program - c

I would like to avoid 'floating point error in this code.
A purpose of this code is to gain 'The average of whole numbers' but the number of 'whole numbers' is limited by the input of users. Please help me.
#include <stdio.h>
int main(void)
{
int num=0;
int limit;
int result=0;
printf("number of integer: ");
scanf("&d", &limit);
while(num<limit)
{
int output;
printf("Input integer : ");
scanf("%d", &output);
result += output;
num++;
}
printf("average of total integer: %d \n", result/limit);
return 0;
}
Thank you for reading.

When you divide 2 integers, the result is also an integer.
To return a float, you need to cast one of the arguments as a float.
So your last line becomes
printf("average of total integer: %f \n", result/(float)limit);

As the result of two integer dividing is also an integer,so it as
printf("average of total integer: %f \n", result/(float)limit);
when you type cast the variable limit to float what happens is that result will be implicitly converted to float and so the result is a float.

Related

Basic C language task about printing a certain number using %.3f

i just started studying programming at school, and i am so lost already. Here's the task:
Answer all 3 tasks in a separate file and return it.
What is the result if the format string (control character) of the printf function is %.3f and the number to be printed is
456.87654321
0.17023
443.14159
How do i even do this? My code is this but it's obviously wrong.
#include <stdio.h>
int main() {
int num1, num2, num3;
printf("Give a number 1\n");
scanf("%i", &num1);
printf("Answer is on %.3f", &num1);
return 0;
}
It gave me 0 as answers or 0.000 what ever. Only 0's.
I don't know what to do really, my teacher is already on another subject and has no time helping me much.
This source code:
#include <stdio.h>
int main(void)
{
printf("%.3f\n", 456.87654321);
printf("%.3f\n", 0.17023);
printf("%.3f\n", 443.14159);
}
produces this output:
456.877
0.170
443.142
You declared num1 to be an int (integer... whole numbers only).
Then you read that number from the keyboard.
I'm guessing you're entering 456.87654321.
(hint, that is not a whole number. it will not fit in an int)
Then you try to print it out with:
printf("Answer is on %.3f", &num1);
This has several problems.
%.3f is for printing out doubles, not ints.
You passed the "address" (& sign) of the number you wanted to print. Just pass the variable directly
Fixing up your code, I get:
#include <stdio.h>
int main() {
double num1; // Declare DOUBLE, not INT
printf("Give a number 1\n");
scanf("%f", &num1); // Get a DOUBLE from input, not an INT
printf("Answer is on %.3f", num1); // Remove the & (address)
return 0;
}

Calculate the discount in a program in C language

I have a plan that gives the total price of the products and if the purchase is more than 200, it should give a 15% discount. But when displaying the final amount, it displays the zero:
#include <stdio.h>
#include <conio.h>
int main()
{
int count;
printf("plz enter number of product :");
scanf("%d", &count);
int price;
int allprice;
float discounted_price ;
int i = 0;
while(i<count)
{
printf("plz enter price %d : ",i+1);
scanf("%d", &price);
allprice +=price;
i++;
}
if(allprice>200)
{
float discount_amount = (15*allprice)/100;
float discounted_price = (allprice-discount_amount);
}
printf("price before discount : %d ",allprice);
printf("\n");
printf("price after discount : %d ",discounted_price);
return 0;
}
You have discounted_price twice.
Once where you calculate it inside the if.
Once outside, which you output.
Outputting hence ignores the calculated value.
Change
float discounted_price = (allprice-discount_amount);
to
discounted_price = (allprice-discount_amount);
And you also need to change the way of printing it, to match the float type
(and thereby avoid undefined behaviour).
printf("price after discount : %f ",discounted_price);
Finally, the amounts will be more precise if you avoid the integer division:
float discount_amount = (15*allprice)/100.0;
And for good measure, init the summation variable (though the effect of that is not always seen) :
int allprice =0;
For readining input by a human (i.e. prone to format errors) it would be wise to check the return value of scanf() and use other verification techniques. But that is beyond the scope of an answer to your question.
First, you should initialize allprice to zero in order to calculate the total.
The inital value of the variable, if not initialized is undefined.
The expression
(15*allprice)/100;
may result in zero because it's doing integer divion since all of the operands (15, allprice, 100) are integers. To avoid this, you can just convert one of the operands to a float, or just add a .0 after 100.
(15*allprice)/100.0f;
This should fix your problem. Let me know if it helps.
The resulting code should look like this:
#include <stdio.h>
#include<conio.h>
int main(){
int count;
printf("plz enter number of product :");
scanf("%d", &count);
int price;
int allprice = 0;
float discounted_price ;
int i = 0;
while(i<count)
{
printf("plz enter price %d : ",i+1);
scanf("%d", &price);
allprice +=price;
i++;
}
if(allprice>200)
{
float discount_amount = (15*allprice)/100.0f;
discounted_price = (allprice-discount_amount);
}
printf("price before discount : %d ",allprice);
printf("\n");
printf("price after discount : %f ",discounted_price);
return 0;
}

A basic error using loops and functions in C

For some reason my code will consistently print out zeros.
I was supposed to make a code in which I enter three numbers,
The first number
The ratio
The amount of numbers to be displayed
The code should display those numbers.
Here is the code:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
void forloop(int firstNum,int ratio,int repeats);
int main(void)
{
int firstNum = 0;
int ratio = 0;
int repeats = 0;
printf("First number of the series: ");
scanf("%d", &firstNum);
printf("the ratio of the series: ");
scanf("%d", &ratio);
printf("the amount of numbers to display is ");
scanf("%d", &repeats);
forloop(firstNum,ratio,repeats);
}
void forloop(int firstNum,int ratio,int repeats)
{
int i = 0;
for (i=1; i!=repeats+1;i++)
{
printf("%d ", firstNum*(pow( ratio, i)));
}
}
This should fix the issue with printing zeros:
void forloop(int firstNum,int ratio,int repeats)
{
int i = 0;
for (i=1; i!=repeats+1;i++)
{
printf("%.0f ", firstNum*(pow((double)ratio,(double)i)));
}
}
As mentioned by #JonathanLeffler in the comments, you have a bug. The line
printf("%d ", firstNum*(pow( ratio, i)));
is wrong because pow returns a double but in the printf specifications %d expects an integer.
So, you can either change the specifier in your printf to a floating point one, i.e., %f, %g, %e, %F, %G, %E et cetera or cast pow's output to int by doing (int)pow(ratio, i).
In the first case, as #JadMrad said, if you are printing a double and you don't want to have decimal numbers, you can specify the number of digits at the right of the decimal point using "%.Nf" instead of "%f" where N is the number of decimal points that you want.
Nevertheless, in your case it seems to me that you are expecting always integer numbers. Then,
printf("%d ", firstNum*((int)pow( ratio, i)));
sounds like a better solution to me.

User enter 5 characters and averge sums out the 5 numbers in C

I been having issues having my C code work. I have 1 warning, which states Warning: too many arguments for format. I am a beginner in C so I haven't encountered this issue yet. Any ideas on how to fix it and I cannot use conditions as I am in the beginning segment of my course learning from the start. I just need to know what I did wrong so I can fix the issue. Here's the code below:
#include <stdio.h>
int main() {
float firstNumber, secondNumber, thirdNumber;
float fourthNumber, fifthNumber;
float sumAverage1 = (firstNumber+secondNumber+thirdNumber);
float sumAverage2 = (fourthNumber+fifthNumber);
long a = 1000000000;
long b = 1250000000;
long c = 1500000000;
long d = 1750000000;
long e = 2000000000;
printf("A is %li\n", a);
printf("B is %li\n", b);
printf("C is %li\n", c);
printf("D is %li\n", d);
printf("E is %li\n", e);
printf("Enter 5 Random numbers and guess what the total will be summed up when program runs.\n");
printf("You cannot enter a decimal integer and enter numbers below 100.\n");
scanf("%f", &firstNumber);
scanf("%f",&secondNumber);
scanf("%f",&thirdNumber);
scanf("%f",&fourthNumber);
scanf("%f",&fifthNumber);
printf("Your numbers average out to:\n", sumAverage1+sumAverage2/5);
system("pause");
return 0;
}
The line:
printf("Your numbers average out to:\n", sumAverage1+sumAverage2/5);
Has an argument but no format specifier. Also, that expression is unparenthesized; the division has higher precedence than the addition, so what you're calculating is sumAverage1+(sumAverage2/5), which is integer division, which is probably not what you want.
What you probably want is:
printf("Your numbers average out to: %f\n", (double)(sumAverage1+sumAverage2)/5.0);
Here this will solve all your problem.
#include <stdio.h>
#include <stdlib.h>
int main() {
float firstNumber, secondNumber, thirdNumber,sumAverage1;
float fourthNumber, fifthNumber,sumAverage2;
long a = 1000000000;
long b = 1250000000;
long c = 1500000000;
long d = 1750000000;
long e = 2000000000;
printf("Enter 5 Random numbers and guess what the total will be summed up when program runs.\n");
printf("You cannot enter a decimal integer and enter numbers below 100.\n");
scanf("%f",&firstNumber);
scanf("%f",&secondNumber);
scanf("%f",&thirdNumber);
scanf("%f",&fourthNumber);
scanf("%f",&fifthNumber);
sumAverage1 = (firstNumber+secondNumber+thirdNumber);
sumAverage2 = (fourthNumber+fifthNumber);
printf("A is %li\n", a);
printf("B is %li\n", b);
printf("C is %li\n", c);
printf("D is %li\n", d);
printf("E is %li\n", e);
printf("Your numbers average out to:%f\n", (sumAverage1+sumAverage2)/5);
system("pause");
return 0;
}
I ran this on my Visual Studio and it works just fine. Hope it Solves your Problem.
You need to change the printf format specifier, but your scanf does not capture the extra dangling newline. You need to either clear the buffer, fflush(stdin) after each scanf() or you need an extra scanf("%c") to get rid of the newline character.
See scanf() leaves the new line char in buffer?

How to refine this code and sort the data being read into the array?

I want to write a C program to read an array, calculate the sum of all individual entries, the average, the minimum grade, the maximum grade, and print all of those values. Is this an effective method of sorting? I'm attempting to sort the data values by min and max comparing it as they are input. My compiler also throws a declaration error with all of the float values.
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
float main()
int i;
float grades[10];
float grade;
float sum;
float avg;
float count;
float max;
float min;
{
max =0;
min=0;
printf("Enter your grades (Type <0 and >100 to quit): ");
scanf("%f", &grade);
sum=0;
i=0;
while(grades>0 && i<10)
{grades[i]= grade;
i++;
if(i<10)
{printf("Enter grade, (Type <0 or >100 to quit): ");
scanf("%f", &grade); }}
for (i=0; i < 10; i++)
{if (grades[i] > max)
{
max=grades[i];
}
else if (grades[i] < min)
{
min = grades[i];
}}
count=i;
for(i=0; i<count; i++)
{printf("Grade %d is %f \n", i+1, grades[i]);}
grade=0;
for(i=0;i<count; i++)
{sum= sum + grades[i];}
if(count>0)
{avg=sum/count;}
else
{avg=0;}
printf("The average of the %f grades is %f \n",count, avg);
printf("The Minimum Grade is %f",min);
printf("The Maximum Grade is %f", max);
printf("Count is %f ", count);
printf("Sum is %f", sum);
printf("Average is %f", avg);
}
The very refided code for solving your problem is
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#define GRADE_ARRAY_LEN 10
int main()
{
int i = 0;
double grades[GRADE_ARRAY_LEN];
double grade;
double max;
double min;
while(i<GRADE_ARRAY_LEN)
{
printf("Enter grade, (Type <0 or >100 to quit): ");
if(scanf("%lf", &grade) != 1)
{
printf("The value entered could not be converted to double. Please enter another value.\n");
scanf("%s");
continue;
}
if(grade < 0.0 || grade > 100.0)
{
return 1;
}
else
{
if(i == 0)
{
max = grade;
min = grade;
}
else
{
if(grade > max)
{
max = grade;
}
if(grade < min)
{
min = grade;
}
}
grades[i]= grade;
i++;
}
}
double sum = 0;
for(i=0; i<GRADE_ARRAY_LEN; i++)
{
printf("Grade %d is %lg \n", i+1, grades[i]);
sum+=grades[i];
}
double avg = sum/GRADE_ARRAY_LEN;
printf("The average of the %d grades is %g \n", GRADE_ARRAY_LEN, avg);
printf("The Minimum Grade is %lg\n",min);
printf("The Maximum Grade is %lg\n", max);
printf("Number of grades is %d\n", GRADE_ARRAY_LEN);
printf("Sum is %lg\n", sum);
printf("Average is %lg\n", avg);
return 0;
}
I may have missed something, but i checked it and it works.
The - How it works is a bit long.
First of all the amount of grades you want to enter is fixed and defined in #define GRADE_ARRAY_LEN 10 which lets you easily change the number of grades you want to enter.
Then the programm reads input and checks if the input is double or can be converted to double. This check is simple if(scanf("%lf", &grade) != 1). scanf() returns the number of arguments successfully filled, the format "%lf" means that you want your input argument to be filled as double. So scanf("%lf", &grade) will return only return a value which equals to 1, if you entered a value that can be converted to double.
Now if the input IS NOT double or double or can be converted to double the program askes you to enter an input which is double or can be converted to double. scanf("%s"); is actully needed because when scanf("%lf", &grade) fails there is a newline char left in the input stream, which you have to actually read. If you don't, next scanf("%lf", &grade) will actually take it as an input, and fail again, thus creating an infinite loop.
After the input is successfully filled, it means you have your value of grade. The program checks what value was entered, and exits if the value is smaller than 0 or greater than 100. I did this because printf actually outputs, that the program will exit if the value is smaller than 0 or greater than 100.
If the value of grade is between 0 and 100, then the program checks if it is the first value that was scanned with this if(i == 0). Where i is the number of successfully scanned values. If i == 0 than no values were scanned yet, so max and min must be initialized with this value for max and min to work correctly., because all other values have to be checked against the first value. If i != 0, then the value is checked against max an min, and they are modified in case of need.
After min and max are checked the value is FINALLY added to our array of values and the number of successfully scanned values is increased.
i++;grades[i]= grade;
i++;
NOTE!!!: all the operations above are commited in one single loop, while(i<GRADE_ARRAY_LEN). This ensures that you enter the correct amount of values and get the correct max and min values. You do not actually need extra loops to get correct min and max values.
After the loop, the sum of grades is counted. After that, the avg of grades is counted.
NOTE!!!: You do not need any checks here because the loop ensures that you enter correct amount of elemets.
In the end the results are printed to a command line.
I'll try to point out the main parts that i edited.
First: variable declarations must be inside the brakets of main() and main must return an int, which means your code had this:
float main()
int i;
float grades[10];
float grade;
float sum;
float avg;
float count;
float max;
float min;
{
but it must be like this
int main()
{
int i = 0;
double grades[GRADE_ARRAY_LEN];
double grade;
double max;
double min;
Second: Your code did not check if scanf("%lf", &grade) successfully filled grade. That is wrong because you can actually enter any combination of characters and numbers in command line, but the only correct input is when you enter a number, that can be converted to double. That means you have to check what scanf returns.
Third: max = 0; and min = 0; is not the correct way to initialize max and min values. min=0; is incorrect, because in case of only positive grades, grade will never be smaller than min, thus min will be always 0. The correct way is to initialize min value is with the first correctly read grade from input, so if there is a smaller value is entered, then min can be changed accordinly. The max=0; is incorrect because in case of only negative grades, grade will never be greater than max, thus max will be always 0. The correct way is to initialize max value is with the first correctly read grade from input, so if there is a greater value is entered, then max can be changed accordinly.
Third: As i said above, you do not actually need a separate loop to find max and min values. It can be done inside the loop where data is read. It is not really nececcary, but it's a good practice to do everything you can inside one loop.
Fourth: It is a good practice to define lenght of arrays with fixed length before main function using #define. Quote: "The #define creates a macro, which is the association of an identifier or parameterized identifier with a token string. After the macro is defined, the compiler can substitute the token string for each occurrence of the identifier in the source file.". That basically means that you add #define GRADE_ARRAY_LEN 10, as shown in code above, before main, and then instead of using 10 as the number of iterations, and number of array elements like double grades[10]; while(i<10); for(i=0;i<10;i++)
you actually use double grades[GRADE_ARRAY_LEN]; while(i<GRADE_ARRAY_LEN); for(i=0;i<GRADE_ARRAY_LEN;i++). The compiler will automaticly substitute GRADE_ARRAY_LEN for 10; Thsi enables you to change 10 for any other number you want (positive of course) only in one place, instead of changing it in several places;
Fifth: printf("Enter grade, (Type <0 or >100 to quit): ") outputs that if you type a value <0 or >100 the program should exit. Considering the input values were not checked at all, this is not happening.
Sixth: while(grades>0 && i<10) is wrong, because grades is an Array, and you can not compare an array to a single number.
Now on to what i actually did to the code to make it work:
1) Moved the var declarations and changed the return value of main
2) Implemented a check for successfull filling of grade by scanf("%lf", &grade).
3) Implemented a program exit in case if input is <0 or >100;. This means the program will actuallly exit if you enter a number smaller than 0 and greater than 100
4) Implemented a #define GRADE_ARRAY_LEN 10 to use as a length of grade array
5) Re-made the loop so it will ask to enter correct input data GRADE_ARRAY_LEN times. Now the program won't continue unless you enter correct input data exactly GRADE_ARRAY_LEN times.
6) Moved the finding of min and max values to the while loop. As said above, you do not actually need a separate loop to find them. Also modified the initialization of min and max
7) Due to changes above, made some changes in the end.
7.1) Changed a little the way sum is counted
Was:
for(i=0;i<count; i++)
{sum= sum + grades[i];}
Now:
double sum = 0;
for(i=0; i<GRADE_ARRAY_LEN; i++)
{
printf("Grade %d is %lg \n", i+1, grades[i]);
sum+=grades[i];
}
7.2) Removed unnecessary check upon calculating avg
Was:
if(count>0)
{avg=sum/count;}
else
{avg=0;}
Now:
double avg = sum/GRADE_ARRAY_LEN;
8) Changed all float values to double. The amount of bytes float allocates for a var is actually dependant on system architecture, where double is actually an Quote: "IEEE 754 double-precision binary floating-point format: binary64".
9) Due to changes above, changed format of the input data from %f to %lf, Changed format of output data from %f to %lg. Now both can work with double.
Replacing this:
double min;
while(i<GRADE_ARRAY_LEN)
{
.......
printf("The value entered could not be converted to double. Please enter another value.\n");
scanf("%s");
With this:
double min;
char c;
while(i<GRADE_ARRAY_LEN)
{
.......
printf("The value entered could not be converted to double. Please enter another value.\n");
scanf("%s", &c);
Should fix the scanf error. The second error is probably because you forgot to copy the closing braket - "}" of main at the very end. What i mean is that you probably have this at the very end:
printf("Average is %lg\n", avg);
return 0;
But!!! it shold be like this
printf("Average is %lg\n", avg);
return 0;
} // !!!!

Resources