Output shows all 0's. The gross and OT is not calculating - c

Output shows all 0's. The gross and OT is not calculating..
#include <stdio.h>
#define STD_HOURS 40.0
#define OT_RATE 1.5
#define SIZE 5
void read_hours(float worked_hours[], long int clockNumber[]);
void calculate_gross(float wage[], float worked_hours[], float gross);
void calculate_gross_ot(float wage[], float worked_hours[]);
void printFunction(long int clockNumber[], float wage[], float worked_hours[], float OT[], float gross);
int i;
int main()
{
long int clockNumber [SIZE] = {98401, 526488, 765349, 34645, 127615};/* employee ID */
float gross = 0.0; /* gross */
float OT [SIZE] = {}; /* overtime */
float wage [SIZE] = {10.6, 9.75, 10.5, 12.25, 8.35}; /* hourly wage */
float worked_hours [SIZE] = {}; // Hours worked
read_hours(worked_hours, clockNumber);
if (worked_hours[i]>STD_HOURS)
{
calculate_gross_ot(wage, worked_hours);
}
else
{
calculate_gross(wage,worked_hours, gross);
}
printFunction(clockNumber, wage, worked_hours, OT, gross);
return(0);
}
void read_hours(float worked_hours[], long int clockNumber[])
{
for (i=0; i<SIZE; i++)
{
printf("\n Enter Hours for Emlployee ID: %ld\n", clockNumber[i]);
scanf ("%f", &worked_hours[i]);
}
}
void calculate_gross(float wage[], float worked_hours[], float gross)
{
for(i=0; i<SIZE; i++)
gross=(wage[i]*worked_hours[i]);
}
void calculate_gross_ot(float wage[], float worked_hours[])
{
float gross;
float OT[SIZE];
for (i=0; i<SIZE; i++)
{
/* calculating overtime hours */
OT[i]=worked_hours[i]-STD_HOURS;
/* calculating gross pay with overtime */
gross = (STD_HOURS*wage[i]) + (OT[i]*OT_RATE*wage[i]);
//}
}
}
void printFunction(long int clockNumber[], float wage[], float worked_hours[], float OT[], float gross)
{
/* creating a table for the output */
printf("------------------------------------------------\n");
printf("%7s","Clock#");
printf("%7s","Wages");
printf("%7s","Hours");
printf("%7s","OT");
printf("%7s\n","Gross");
printf("------------------------------------------------\n");
for (i=0; i<SIZE; i++)
{
/* printing the results */
printf("%6ld", clockNumber[i]);
printf("%10.2f",wage[i]);
printf("%6.1f", worked_hours[i]);
printf("%6.1f", OT[i]);
printf("%10.2f",gross);
printf("\n");
}
}
The program is used to calculate gross with and without OT hours. The output is showing all 0's for the gross and OT. Please help to figure out where is the mistake.

In the first case, you are passing gross by value.
In the second case, you are not passing it at all (the function has a local function called gross).
In both cases, whenever the respective function changes gross, this change does not propagate to the caller.
You need to either pass gross by pointer, or return the value from the function using the return statement (and changing the return type appropriately).

Pass OT to your calculate_gross_ot() function from main().
...
calculate_gross_ot(wage, worked_hours, OT);
...
void calculate_gross_ot(float wage[], float worked_hours[], float OT[])

Related

Not able to find my segmentation fault in this code of t-test

I have written this program for t-test. I'll add other functions as well, but first, I need to find my error. Here's my code
# include <stdio.h>
# include <math.h>
float mean(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += x[i];
return sum/size;
}
float sumsq(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += pow(x[i]-mean(x,size),2);
return sum;
}
int input(n)
{
float x[n];
printf("Enter the values one by one");
for (int i = 0; i<n;i++)
scanf("%f", &x[i]);
return x;
}
void t_check(float x)// Make sure to write this function before each of the t-tests. That is because it is of void type. If the t-test is done before the checking function is declared, then it assumes it's datatype to be "int", and we get an error. So either write the t-check function before those functions, or just define it at the beginning of the program
{
float t_tab;
printf("Enter the tabulated value of t");
scanf("%f",&t_tab);
if (x<t_tab)
printf("We do not have enough evidence to reject the null hypothesis");
else
printf("Reject the null hypothesis");
}
float t_diff_of_means()
{
float x=0.0,y=0.0,s1=0.0,s2=0.0,S=0.0,t=0.0,tcal;
int n,m,a,b;
printf("Enter the number of variables in population 1");
scanf("%d", &n);
a = input(n);
printf("Enter the number of variables in population 2");
scanf("%d", &m);
b = input(m);
x = mean(a,n);
y = mean(b,m);
s1 = sumsq(a, n);
s2 = sumsq(b, m);
S = sqrt((s1+s2)/(n+m-2));
t = (x-y)/(S*sqrt(1.0/n+1.0/m));
t_check(t);
}
int main(void)
{
t_diff_of_means();
return 0;
}
It gives segmentation fault as an error. I'm not able to understand where my code uses any memory uses a part of memory that is not allocated to it
The main issue is you expect input() to read an array floats but you return an int. You should declare the type of the argument n. You cannot return an address to a local variable as it out of scope for caller. The easiest option is to the declare the array variable in main() then pass it to input to populate (pun). (not fixed) Check that return value of scanf() otherwise the variable you expect to be initialized may not be.
t_diff_of_means() is declared to return a float but nothing is returned. Not sure what you want to return so I changed the return type to void.
Tweaked various prompts to make it more them more readable.
#include <stdio.h>
#include <math.h>
float mean(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += x[i];
return sum/size;
}
float sumsq(float x[], int size)
{
float sum = 0.0;
for (int i=0; i<size;i++)
sum += pow(x[i]-mean(x,size),2);
return sum;
}
void input(size_t n, float a[n])
{
printf("Enter the values one by one: ");
for (int i = 0; i<n;i++)
scanf("%f", a+i);
}
void t_check(float x)
{
float t_tab;
printf("Enter the tabulated value of t: ");
scanf("%f",&t_tab);
if (x<t_tab)
printf("We do not have enough evidence to reject the null hypothesis\n");
else
printf("Reject the null hypothesis\n");
}
void t_diff_of_means()
{
float x=0.0,y=0.0,s1=0.0,s2=0.0,S=0.0,t=0.0;
int n,m;
printf("Enter the number of variables in population 1: ");
scanf("%d", &n);
float a[n];
input(n, a);
printf("Enter the number of variables in population 2: ");
scanf("%d", &m);
float b[m];
input(m, b);
x = mean(a,n);
y = mean(b,m);
s1 = sumsq(a, n);
s2 = sumsq(b, m);
S = sqrt((s1+s2)/(n+m-2));
t = (x-y)/(S*sqrt(1.0/n+1.0/m));
t_check(t);
}
int main(void)
{
t_diff_of_means();
return 0;
}
and example run:
Enter the number of variables in population 1: 2
Enter the values one by one: 1
2
Enter the number of variables in population 2: 2
Enter the values one by one: 2
3
Enter the tabulated value of t: 0.05
We do not have enough evidence to reject the null hypothesis
Consider eliminating the variables you only use once (x, y, s1, s2, S, t and t_cal):
t_check(
(mean(a, n) - mean(b, m)) / (sqrt((sumsq(a, n)+sumsq(b, m))/(n+m-2))*sqrt(1.0/n+1.0/m))
);
then I observed that this only depends on variables a, n, b and m so push that calculation into t_check():
void t_check(size_t a_len, float a[a_len], size_t b_len, float b[b_len]) {
float t = (mean(a, a_len) - mean(b, b_len)) / (sqrt((sumsq(a, a_len)+sumsq(b, b_len))/(a_len+b_len-2))*sqrt(1.0/a_len+1.0/b_len));
// ...
}
Then I changed the length types to size_t and used the clearer variable names in t_diff_of_means():
void t_diff_of_means()
{
printf("Enter the number of variables in population 1: ");
size_t a_len;
scanf("%zu", &a_len);
float a[a_len];
input(a_len, a);
printf("Enter the number of variables in population 2: ");
size_t b_len;
scanf("%zu", &b_len);
float b[b_len];
input(b_len, b);
t_check(a_len, a, b_len, b);
}
We could take this another step by observing the two first sections in t_diff_of_means() are very similar, so we could have input() take a prompt and a pointer to an array of floats along with elements read. input() would then need to dynamically allocate the array of floats. This means most of our functions take a array of float and length argument. Let's create a type for that and refactor our functions to use it:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
struct array {
size_t len;
float *data;
};
float mean(struct array *a)
{
float sum = 0;
for (int i=0; i<a->len;i++)
sum += a->data[i];
return sum/a->len;
}
float sumsq(struct array *a)
{
float sum = 0;
for (int i=0; i<a->len;i++)
sum += pow(a->data[i] - mean(a), 2);
return sum;
}
void input(int prompt, struct array *a)
{
printf("Enter the number of variables in population %d: ", prompt);
scanf("%zu", &a->len);
a->data = malloc(a->len * sizeof(a->data[0]));
//if(!a->data) ...
printf("Enter the values one by one: ");
for (int i = 0; i<a->len;i++)
scanf("%f", &a->data[i]);
}
void t_check(struct array a[2])
{
float t = (mean(a) - mean(a+1)) / (
sqrt(
(sumsq(a) + sumsq(a+1)) / (a[0].len + a[1].len-2)
) * sqrt(1.0/a[0].len + 1.0/a[1].len)
);
printf("Enter the tabulated value of t: ");
float t_tab;
scanf("%f",&t_tab);
if (t<t_tab)
printf("We do not have enough evidence to reject the null hypothesis\n");
else
printf("Reject the null hypothesis\n");
}
int main(void)
{
struct array a[2];
input(1, a);
input(2, a+1);
t_check(a);
}
This would be a good base to add additional functions to.

Printf function pass by reference

I'm trying to make a simple program with C that gets name, hourly rate and hours for input and calculates gross pay, tax, net pay etc, but I got stuck as I was making a function that prints out results.
I created two loops: one loop that generates overtime, gross pay, tax and net pay. Another loop that prints out the generated data. First one works fine. It generates data just fine, but as I run the program, it simply ignores the second loop and just finish the program.
It is just a simple void function that has no return value, and yet I'm stuck. I used pass by reference. If you know what's wrong, please let me know.
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
#define size 5
char name[size][20];
float rate[size];
float hours[size];
int i = 0;
void input();
float getbasepay(float *rt, float *hr);
float getovtime(float *rt, float *hr);
float getgross(float *base, float *ovt);
float gettax(float *gross);
float getnetpay(float *gross, float *tax);
void printout(char name, float rate, float hours, float base, float ovt, float gross, float tax, float net);
void input()
{
for (i = 0; i < size; i++)
{
puts("\ntype name: (type -1 to quit) \n");
scanf_s("%19s", &name[i], 20);
if (strcmp(name[i], "-1") == 0) { break; }
puts("\ntype hourly rate: (type -1 to quit) \n");
scanf_s("%f", &rate[i]);
if (rate[i] == -1) { break; }
puts("\ntype hours worked: (type -1 to quit) \n");
scanf_s("%f", &hours[i]);
if (hours[i] == -1) { break; }
}
return ;
}
float getbasepay(float *rt, float *hr)
{ float base;
float baseo;
float excessive = (*hr - 40);
if (*hr <= 40)
{
base = (*rt) * (*hr);
return base;
}
if (*hr >= 40)
{
baseo = (*hr - excessive) * (*rt);
return baseo;
}
}
float getovtime(float *rt,float *hr)
{
float time;
float ovt;
if (*hr >= 40)
{
time = (*hr - 40);
ovt = time * (*rt) *1.5;
return ovt;
}
else
{
return 0;
}
}
float getgross(float *base, float *ovt)
{
float gross = *base + *ovt;
return gross;
}
float gettax(float *gross)
{
float tax = *gross * 0.20;
return tax;
}
float getnetpay(float *gross, float *tax)
{
float net;
net = *gross - *tax;
return net;
}
void printout(char *name, float *rate, float *hours, float *base, float * ovt, float *gross, float *tax, float *net)
{
printf("\nPay to: %s \n", *name);
printf("Hourly rate: %f \n", *rate);
printf("Hours: %f \n", *hours);
printf("Base pay: $%f \n", *base);
printf("Overtime: $%f \n", *ovt);
printf("Gross Pay: $%f \n", *gross);
printf("Tax: $%f \n", *tax);
printf("Net Pay: $%f \n", *net);
}
int main(void)
{
int o, z;
float overtime[size] = { 0,0,0,0,0, };
float basepay[size] = { 0,0,0,0,0, };
float tax[size] = { 0,0,0,0,0, };
float grosspay[size] = { 0,0,0,0,0, };
float netpay[size] = { 0,0,0,0,0, };
float sum;
input();
for (o = 0; o < i; o++)
{
basepay[o] = getbasepay(&rate[o], &hours[o]);
overtime[o] = getovtime(&rate[o], &hours[o]);
grosspay[o] = getgross(&basepay[o], &overtime[o]);
tax[o] = gettax(&grosspay[o]);
netpay[o] = getnetpay(&grosspay[o], &tax[o]);
}
for (z = 0; z > i; z++)
{
printout(&name[z], &rate[z], &hours[z], &basepay[z], &overtime[z], &grosspay[z], &tax[z], &netpay[z]);
}
}
Your code doesn't compile:
gcc -o main main.c
Answers:
error: conflicting types for ‘printout’
And indeed, the signature in the declaration is different than the one you
wrote in the implementation (for example char *name instead of char name etc.)

Program Variance and Standard Deviation Using Pointer Function

So i'm trying to make a standard deviation and variance function and I can't really figure out why it doesn't work. I'm suppose to call variance in case 3 and SD in case 4. everything else works in the program. If you see anything that doesn't look right let me know.
#include <stdio.h>
#include <math.h>
#define Max_Nums 20
void sortNums(float nums[], int size);
float meanValue(float nums[],int size);
float medianValue(float nums[], int size);
void var_stdDev(float nums[],int size,float *var,float *stdDev);
float sqrtf(float);
int main (void)
{
int NumValue = 0;
float array[Max_Nums];
int i=0;
int choice=0;
float avg=0;
float median=0;
printf("How many numbers do you wish to enter (Max of 20): ");
scanf("%d",&NumValue);
while (NumValue<1 || NumValue>Max_Nums)
{
printf("Invalid response. You must enter a value between 1 and 20.\n");
scanf("%d",&NumValue);
}
printf("Enter %d real numbers: ",NumValue);
for (i=0;i<NumValue;i++)
{
scanf("%f", &array[i]);
}
do
{
sortNums(array,NumValue);
printf("-----Menu-----\n\a");
printf("Enter 1 for mean value\n");
printf("Enter 2 for median value\n");
printf("Enter 3 for variance\n");
printf("Enter 4 for standard deviation\n");
printf("Enter 5 to exit the program\n");
scanf("%d",&choice);
switch(choice)
{
case 1:
avg=meanValue(array,NumValue);
printf("The mean is:%.2f\n",avg);
break;
case 2:
median=medianValue(array,NumValue);
printf("The median is:%.2f\n",median);
break;
case 3:
//printf("The variance is:%.2f",variance);
//break;
case 4:
//printf("The standard deviation is:%.2f\n");
//break;
case 5:
printf("Exiting the program\n");
break;
default:
printf("\nInvalid, try again");
break;
}
}while (choice!=5);
return 0;
}
void sortNums(float nums[], int size)
{
int x;
int y;
float z;
for(x=0;x<(size-1);x++)
{
for(y=0;y<size-x-1;y++)
{
if(nums[y]>nums[y+1])
{
z=nums[y];
nums[y]=nums[y+1];
nums[y+1]=z;
}
}
}
}
float meanValue(float nums[],int size)
{
int i;
float avg;
float sum;
for(i=0;i<size;i++)
{
sum+=nums[i];
}
avg = (sum/size);
return avg;
}
float medianValue(float nums[], int size)
{
float EvenMed;
float Med;
void sortNums(float nums[], int size);
if (size%2==0)
{
EvenMed=(nums[size/2]+nums[size/2-1])/2;
return EvenMed;
}
else
{
Med=nums[size/2];
return Med;
}
}
void var_stdDev(float nums[],int size,float *var,float *stdDev)
{
int i;
float sum;
float meanValue(float nums[],int size);
for(i=0;i<size;i++)
{
sum+=pow((nums[i]-meanValue,2);
}
*var=sum/(float)size;
*stdDev=sqrt(*var);
}
This line is wrong:
sum+=pow((nums[i]-meanValue,2);
This is trying to subtract a function pointer from a number, which makes no sense. You need to call the meanValue function to get the mean, and then subtract that.
Also, you didn't initialize sum before adding to it.
void var_stdDev(float nums[],int size,float *var,float *stdDev)
{
int i;
float sum = 0;
float mean = meanValue(nums, size);
for(i=0;i<size;i++)
{
sum+=pow((nums[i]-mean,2);
}
*var=sum/(float)size;
*stdDev=sqrt(*var);
}
There's no need to have a declaration of meanValue inside var_stdDev, the declaration at the top of the file serves that purpose throughout.
In medianValue(), you have a declaration of sortNums(), but you never call it, so the numbers aren't sorted (it seems like you don't understand the difference between a prototype and a call).
float medianValue(float nums[], int size)
{
float EvenMed;
float Med;
sortNums(nums, size);
if (size%2==0)
{
EvenMed=(nums[size/2]+nums[size/2-1])/2;
return EvenMed;
}
else
{
Med=nums[size/2];
return Med;
}
}
As well explained by #Barmar , OP's code has a number of problems:
void var_stdDev(float nums[],int size,float *var,float *stdDev) {
int i;
// sum not initialize
float sum;
// unneeded function declaration
float meanValue(float nums[],int size);
// missing code to find the mean
for(i=0;i<size;i++) {
// improper call to accumulate the average derivation from the mean
sum+=pow((nums[i]-meanValue,2);
}
...
Recommend a new approach to standard deviation calculation
from here
std = sqrt(n*sum_of_squares - sum_of_x*sum_of_x)/n
Suggested improvements:
Use double for intermediate calculation. float is fine to reduce storage and sometimes for speed. Yet statistics often subtract values leading to significant lost of precision. Use double.
Due to rounding, select data sets could result in a tiny negative number - even if mathematically the result should be >= 0.0. So good to check sign before sqrt().
Handle case when size == 0 and do not perform a run-time division by 0.
void var_stdDev2(const float x[], size_t size, float *var, float *stdDev) {
double sumx = 0.0;
double sumxx = 0.0;
double std = 0.0; // Used when size == 0.0 - or set to NaN
if (size > 0) {
for (size_t i = 0; i < size; i++) {
sumx += x[i];
sumxx += 1.0 * x[i] * x[i];
}
double std = sumxx * size - sumx * sumx;
std = std >= 0.0 ? sqrt(std) : 0.0;
std /= size;
}
if (stdDev) *stdDev = (float) std;
if (var) *var = (float) sqrt(std);
}
Minor bits:
Use a const in the signature as function does not modify nums[].
Array are best indexed with size_t rather than int.

Custom average function with array input does not return value in C

I made a program which accepts input for 30 users (About their age)
and then the array was supposed to be an input in a custom function made by me (avg_age)
However the average printed on screen is 0.0000 (for 30 non-zero values)
That is why I think it does not return anything.
#include <stdio.h>
float avg_age(int age[]);
main()
{
int i=0,age[30]={0},intemp;
do{
printf("Input age for 30 users: ");
scanf("%d",&intemp);
if(intemp>0 && intemp<100)
intemp=age[i];
else i--;
i++;
}while(i<30 || intemp<0 || intemp>100);
printf("\nAverage age of 30 users: %f\n",avg_age(age));
float avg_age(int age[]){
int i,avg=0;
for(i=0;i<30;i++)
avg+=age[i];
avg=(float)avg/30;
return avg;
}
}
Take out the function definition of avg_age out of the main. You declared avg as int but it should be declared float to store float values.
float avg = 0.0;
In main intemp=age[i]; is not storing the inputs to the array age instead assigning 0 each time to intemp. Change it to
age[i] = intemp;
Your modified code: (for 5 users)
#include <stdio.h>
#define N 5
float avg_age(int age[]);
int main(void)
{
int i=0,age[N]={0},intemp;
do{
printf("Input age for %d users: ", N);
scanf("%d",&intemp);
if(intemp>0 && intemp<100)
age[i] = intemp;
else i--;
i++;
}while(i<N || intemp<0 || intemp>100);
printf("\nAverage age of %d users: %f\n",N, avg_age(age));
return 0;
}
float avg_age(int age[]){
int i;
float avg=0.0;
for(i=0;i<N;i++)
avg+=age[i];
avg=(float)avg/N;
return avg;
}
Here is the tested code.
Your avg inside avg_age should be a float
float avg_age(int age[]){
int i; float sum=0.0;
for(i=0;i<30;i++)
sum += age[i];
return sum/30;
}
and of course the above function should be outside of main (preferably before it).
BTW, you should have compiled with all warnings and debugging info (e.g. with gcc -Wall -g). The compiler certainly would have warned you! Also, learn how to use the debugger (e.g. gdb)

Calculator program issue in C

I'm writing a statistical calculator, with 3 different calculation options. The problem is whenever I choose the 2nd option, it wants to print both the answer from the 1st option and the 2nd option. When I choose the 3 option, it just prints the answer the the 3rd option(the wrong answer, but thats probably a mishap in the formula). Here is the results:
Please Enter a number of inputs
3
Please enter number 1
1
Please enter number 2
2
Please enter number 3
3
Statistical Calculator Menu
(1) Mean
(2) Standard Deviation
(3) Range
(4) Restart/Exit
2
Here is the Mean 2.0Standard Devition is 0.8
Now I thought it might be an issue with how I'm calling each function, but the best I can tell thats not the case. Then I thought it might be a value that I didn't initialize, but it seems as though thats not it either. I just need another pair of eyes to see where I went wrong here.
#include <stdio.h>
#include <conio.h>
#include <math.h>
const int MAX_DATA=8;
void menu(float numbers[], int amount);
float mean(float numbers[],int amount);
float standard_dev(float numbers[], int amount);
float range( float numbers[], int amount);
int main()
{
int i=0, amount=0;
float numbers[MAX_DATA];
printf("Please Enter a number of inputs \n");
scanf("%d", &amount);
if (amount>MAX_DATA)
{
printf("You entered too many numbers");
}
else
{
for (i=0; i<amount; i++)
{
printf("Please enter number %d\n", i+1);
scanf("%f",&numbers[i]);
}
menu(numbers,amount);
}
getch();
return 0;
}
void menu(float numbers[],int amount)
{
int input2=0;
printf("Statistical Calculator Menu");
printf("\n(1) Mean\n(2) Standard Deviation\n(3) Range\n(4) Restart/Exit\n");
scanf("%d",&input2);
if(input2==1)
{
mean(numbers,amount);
}
if (input2==2)
{
standard_dev(numbers,amount);
}
if (input2==3)
{
range(numbers,amount);
}
}
float mean(float numbers[],int amount)
{
int i;
float sum=0;
float average=0;
for (i=0; i<amount; i++)
{
sum=sum+numbers[i];
}
average=sum/amount;
printf("Here is the Mean %.1f", average);
return average;
}
float standard_dev(float numbers[], int amount)
{
float sdev=0,dev=0,sumsqr=0,variance=0;
int i;
float mean2=0;
mean2=mean(numbers,amount);
for (i=0; i<amount; i++)
{
dev=numbers[i]-mean2;
sumsqr+=dev*dev;
}
variance=sumsqr/(float)amount;
sdev=sqrt(variance);
printf("Standard Devition is %.1f", sdev);
return sdev;
}
float range(float numbers[],int amount)
{
int i;
float diff=0;
for (i=0; i<=amount; i++)
{
diff=numbers[amount]-numbers[1];
}
printf("%f\n",diff);
return diff;
}
float standard_dev(float numbers[], int amount)
{
float sdev=0,dev=0,sumsqr=0,variance=0;
int i;
float mean2=0;
mean2=mean(numbers,amount); // Here it is.
It calls the mean function, which actually prints something :) You can add boolean flag shouldPrint to functions and pass it as true when you want to print it.
Also, this problem is easily solvable with simple debugging your code...if actually looking at it doesn't seem to help...

Resources