I am trying to keep a count of how many times the operation inside the do-while loop is repeating, but the counter only shows 1 each time. Can anyone tell me where is my mistake? I have provided the code here.
#include <stdio.h>
#include <math.h>
int main(void)
{
double i = 84;
int counter = 0;
do {
counter++;
i = fmod(i, 25.0);
}
while(i > 25);
printf("Counter: %i\n %lf\n", counter, i);
}
fmod is floating point modulo.
It cannot return something higher than 25.0 since you've passed 25.0 as the modulo value.
That's why while(i>25) is false at the first iteration.
i = fmod(i, 25.0);
This takes the current value of i and finds the remainder of its division by 25. Following that, the remainder is reassigned to i.
double i = 84;
This sets the initial value of i to 84. If we do 84 % 25, we get 9.0. And since 9.0 < 25.0, the loop will terminate after the first operation. Therefore, counter is only incremented once in your loop.
Related
The C code at bottom usually operates as expected, using gcc on Ubuntu 20.04, but about 15% of the time I get a huge result for highest temp:
Normal:
Highest temp: 15.30
15% of the time:
Highest temp: 970363834813736688025683948382903403895871057............00
If I pull the the function out of the printf() call, things behave as expected 100% of the time:
double max = maxTemp(temperatures,7);
printf("Highest temp: %.2lf\n", max);
I'm assuming the error case is a huge number because there's a double with garbage data somewhere.
Any idea what's going on?
Thank you for your time.
#include <stdio.h>
double maxTemp(double *temps, int numOfTemps);
int main(void) {
double temperatures[7] = {6.9, 12.3, 9.0, 15.3, 9.8, 1.8, 0.3};
printf("Highest temp: %.2lf\n", maxTemp(temperatures, maxTemp(temperatures,7)));
return 0;
}
double maxTemp(double *temps, int numOfTemps) {
double max = temps[0];
for (int i = 0; i < numOfTemps; i++) {
if (max < temps[i]) {
max = temps[i];
}
}
return max;
}
This is your problem:
maxTemp(temperatures, maxTemp(temperatures,7)))
maxTemp expects its second argument to have type int and to be the number of elements in the temperatures array. In the outer call, you're passing the result of maxTemp, which is a double, and is a temperature, not a count of array elements.
The compiler should be yelling at you right there - if not, turn on all warnings and treat all warnings as errors (-Wall -Werror if you're using gcc).
Secondly, the max temperature in your array is 15.3 - assuming that gets converted to an int value of 15, you're iterating past the end of your array into garbage.
Are you sure you don't mean to call that as
maxTemp( temperatures, 7 );
?
as one comment pointed out, you're calling maxTemp(…) twice in main.
If you remove the "outer call" you'll be fine, i.e. changing main to:
int main(void) {
double temperatures[7] = {6.9, 12.3, 9.0, 15.3, 9.8, 1.8, 0.3};
printf("Highest temp: %.2lf\n", maxTemp(temperatures, 7));
return 0;
}
Reason being that maxTemp(temps, n) calculates the maximum of n temperatures. So it will only work properly (defined behavior) if n is the actual number of values. This does usually not apply to the max temp.
This means you were taking values into consideration that are outside of the temperatures-array.
why it worked sometimes (by accident)
Those values outside your array are undefined. Values outside of allocated space are often 0, but not by definition. This is why it worked most of the time.
The goal of the program is to perform a checksum in the following way: multiply every other digit by 2, starting with the number’s second-to-last digit, and then add those products’ digits together.
Add the sum to the sum of the digits that weren’t multiplied by 2. If the total modulo 10 is 0, the number is valid The problem with my code is that it runs forever, therefore I suppose something is wrong with the loops, any suggestion on why that might be happening and how to fix it? Note:
#include <stdio.h>
#include <cs50.h>
#include <math.h>
double input(void);
int main(void)
{
double number = input();
double sum = 0;
double i = 1;
double current_digit;
do
{
current_digit = (fmod(number, pow(10,i)) - fmod(number, pow(10, i-1)))/pow(10, i-1); //formula to calculate the ith digit in a number
if (fmod(i,2) != 0)
{
sum += current_digit;
}
else
{
double second_number = 2*current_digit;
double j = 1;
do
{
double second_current_digit = (fmod(second_number, pow(10,j)) -fmod(second_number,pow(10, j-1)))/pow(10, j-1);
sum += second_current_digit;
j++;
}
while (fmod(second_number, pow(10,j)) == number);
i++;
}
}
while (fmod(number,pow(10, i)) != number);
if (fmod(sum,10) == 0)
{
printf("true");
}
else
{
printf("false");
}
}
double input(void)
{
double number = get_double("Number: ");
return number;
}
the usage of double ... the program will have to take in 16 digits or even more, I didn't know what to do to handle larger integers, maybe long type?
Most computers these days support 64-bit integers natively. Those can give you as many as floor(log_10(2^64)) = 19 decimal digits. If that's sufficient, use uint64_t from <stdint.h> (it's a type defined in the C standard).
If that's not sufficient, consider using an array of digits, or a more involved "big integer" data type, as in here.
Anyway, I'm betting the exact floating-point comparison is what's biting you, as, probably, the value of pow(10,i) is not an exact power of 10, so the fmod() changes number slightly. But - don't trust my guess, just use a debugger:
In a terminal: How to Debug C Program using gdb in 6 Simple Steps, or
In a graphic IDE: For example, Debugging C using Visual Studio Code on Linux.
I am having a problem finding a good approximation to the integral between 0 and infinity of sin(x)/sqrt(x) in C programming. I am trying to use the trapezium rule. In my code I also want the user to input a precision value such as 0.001 where the output value will be accurate to that amount of decimal places. What is going wrong with this code?
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main(void)
{
int i, N; // integers to interate on in loops //
double h, x, y, precision, lowerLim = 0.0001, upperLim = 10000, f0, fN;
printf("accuracy:");
scanf("%lf", &precision);
N = 10;
double areastored, newarea;
do {
newarea = 0.0;
areastored = newarea; // areastored is the area that I want to compare to the new area calulated as the N (number of partitions) to check the precision of the new value to see if it a better approximation //
h = (upperLim - lowerLim)/(N-1);
fN = sin(upperLim)/sqrt(upperLim);
f0 = sin(lowerLim)/sqrt(lowerLim); // end points evaluated in function //
newarea = newarea + 0.5*h*(f0 + fN);
for (int i = 1; i < N; i++) {
x = lowerLim + h*i;
y = sin(x)/sqrt(x);
newarea = newarea + y*h; // this loop adds all the middle trapezia areas //
}
printf("at N %d integral %f\n", N, newarea);
N = N*5; // iterate the N so next round of the loop it will approximate an area with more and smaller trapezia //
} while ( fabs ( newarea - areastored ) > precision ); // if this is false then should have an area to the desired precision //
printf("The integral evaluates to: %lf\n", newarea);
}
The problem is that if I input an accuracy 0.01, the area is calculated for N = 10, 50, 250 but isn't able to continue and the last area = 8.53 which is off the value of 1.253... I'm expecting
EDIT: I have now made suggested changes to the above code as can be seen now thanks to the comments from several users below. Thank you very much for your help! I have now got an issue with my output, see the attached image of my terminal. It should have stopped by the 9th iteration of N for this input and so the printed vale is rather baffling. Why has this occured? Thanks again for any help in advance!
There are at least two errors in your code
// ...
newarea = 0.0; // <-- It's initialized here
do {
// ...
h = (upperLim - lowerLim)/N-1; // <-- This doesn't do what you think
// ...
// It's updated, but never reset
newarea = newarea + 0.5*h*(f0 + fN);
// ...
} while ( ... );
You should move the newarea = 0.0; line inside the loop and modify the formula that calculates h.
Also note that you have a fixed upper limit (1000), while for this type of integrals you should consider an increasing upper limit and maybe a non uniform grid spacing.
If you debug your program you will see that
h = (upperLim - lowerLim)/N-1;
leads to a negative value of h for N=1250.
This leads to an endless loop
for (x=lowerLim+h; x < upperLim; x+=h) {
because when x gets to a large enough absolute value it will no longer change when you add h.
You probably mean
h = (upperLim - lowerLim) / (N-1);
I need to learn how to use the function for the calculation and then a simple call in main. When I tried it didn't work. I have no idea what to do. It works but when I take out the code from main it gets funky.
this is simple simple scenario and code for that.
Write a function that takes an array of ints, and the size of the array - another int.
It also returns a double. Call this one 'average.' Return a double that is the average
of the values in the array. Demonstrate that it works by finding the average of an array
with these values {78, 90, 56, 99, 88, 68, 92}
#include <stdio.h>
#include <stdlib.h>
// Outside of main, a function will be declared that takes an array of ints.
double Function(int Array[7])
{
// int Array[7] = {78, 90, 56, 99, 88, 68, 92};
int sum = 0;
int i;
double average;
// This for loop allows us to use all 7 elements in the array.
for(i=0; i<7; i++)
{
// This takes all the array's elements and sums them up.
sum += Array[i];
}
// This prints the sum
printf("Sum = %d\n", sum);
// The double average is found by taking the sum found and dividing it by 7.
average = sum/7;
// This prints the average in a double.
printf("The resulting average is %lf \n", average);
return average;
} // Ends Function
// There will also be the size of the array(which is another int)
// The function will return a double called average. It is the average of the values in the array.
int main()
{
//int i; // Allows us to use the for loop and print each element in the corresponding array.
// int array numbers are declared and initialized.
int Array[7] = {78, 90, 56, 99, 88, 68, 92};
int sum = 0;
int i;
double average;
// This for loop allows us to use all 7 elements in the array.
for(i=0; i<7; i++)
{
// This takes all the array's elements and sums them up.
sum += Array[i];
}
// This prints the sum
printf("Sum = %d\n", sum);
// The double average is found by taking the sum found and dividing it by 7.
average = sum/7;
// This prints the average in a double.
printf("The resulting average is %lf \n", average);
Function(Array);
system("pause");
return 0;
}
Can any one give me a tips!
If you want to follow the instruction you were given, your function declaration should be
double average(int *array, int array_size)
Also, your solution should be general, not only for array with length of 7.
In general in C language - when you want to pass an array which its length is unknown, you pass the address of the array (here *array) and its size (here array_size). Then your function will iterate over the array from the given address, with jumps of the type (here jumps of sizeof(int) because it's an array of ints).
In C Program execution always starts from main.
So the stack will be like
main()-->Function()
You are almost right just you called the function which returns the average so to keep that average or to accept that average in main you need variable so just remove all the code shown below
for(i=0; i<7; i++)
{
// This takes all the array's elements and sums them up.
sum += Array[i];
}
// This prints the sum
printf("Sum = %d\n", sum);
// The double average is found by taking the sum found and dividing it by 7.
average = sum/7;
// This prints the average in a double.
printf("The resulting average is %lf \n", average);
Now take the results returned by the Function() in average variable shown below.
average=Function(Array);
Now print that value if you want to print or use in main if you need.
the posted code contains several misconceptions
no need to '#include' header files those contents are not needed.
only write code that is part of the solving of the problem. Other code that is added for 'debug' purposes should be eliminated from the final executable. Usually be surrounding the debug code with: #ifndef NDEBUG .... #endif Suggest learning how to work with NDEBUG
The problem only needs to solved once, not both in 'main()' and in 'Function()' BTW: function is a terrible function name suggest: calculateAverage(). Function names should indicate what they will perform, usually by starting the function with some active verb, like calculate
for ease of readability and understanding, consistently indent the code. Indent after every opening brace '{'. unindent before every closing brace '}'. Suggest each indent level be 4 spaces as that is wide enough to be visible even with variable width fonts. Remember, the compiler (in general) doesn't care about the 'style' of the code formatting. However, any human cares a lot, because the human wants to be able to read the code.
it is (almost always) a bad idea to hard code any values other than 0 and 1. Instead give them meaningful names via a enum statement or #define statements, then use those meaningful names throughout the code.
Please pay attention to these 3 details in the code:
how the size of the array is calculated
how the parameters are passed to the 'Function()'
how the average is calculated.
Note: when all the variables in a divide operation are integers, then a integer divide is performed. This can produce some surprising results.
For instance, 5/3 results in 1, not 1.66.
by wanting to keep the fraction, cast one of the elements (not the whole expression) to double or float
and now the code
#include <stdio.h> // printf()
//#include <stdlib.h>
double Function(int *pArray, int numElements );
int main( void )
{
// int array numbers are declared and initialized.
// note: usually best to let the compiler calculate array size
// rather than hardcoding the size
int Array[] = {78, 90, 56, 99, 88, 68, 92};
// number of elements in array
int sizeofArray = sizeof(Array)/sizeof(int);
// call Function to calculate and return as double,
// the average of the array elements
double average = Function( Array, sizeofArray );
// This prints the average as a 'double'.
printf("The resulting average is %lf \n", average);
//system("pause"); // not portable, suggest:
int ch;
while( (ch = getchar()) != EOF && '\n' != ch );
getchar();
//return 0; // <-- in modern C, if main to return 0 then this line not needed
} // end function: main
double Function(int *pArray, int numInts )
{
int sum = 0;
double average;
for(int i=0; i<numInts; i++)
{
sum += pArray[i];
}
// cast one of the values as a double so an integer divide is NOT performed
average = (double)sum / numInts;
return average;
} // end function: Function
I'm new at programming, new on this site too, so hello...
I'm attempting to obtain a running total for integers one thru 10, but I'm getting gibberish answers and I just can't understand why.
To attempt to find out what was going wrong, I added the
printf(" running total is %d\n", sum);
line to the while loop, but just got more of the same nonsense...
please see http://codepad.org/UxEw6pFU for the results....
I'm sure this has a blindingly obvious solution...I'm just too dumb to see it though!
anyone know what I'm doing wrong?
#include <stdio.h>
int main(void) {
int count,sum,square;
int upto=10;
count = 0;
square = 0;
while (++count < upto) {
square = count * count;
printf("square of %d is %d",count,square);
sum =square + sum;
printf(" running total is %d\n", sum);
}
printf("overall total of squares of integers 1 thru 10 is %d\n", sum);
return 0;
}
You need to initialize sum to 0.
EDIT As others have stated after the fact, the reason you're seeing garbage is because sum isn't initialized and contains whatever is in memory. It can be anything, and your use of it with sum = square + sum is going to add square to the uninitialized value.
You are never initializing the value of sum.
The first time your code runs
sum = square + sum;
The value of sum (on the right side) is an arbitrary number because it has not been initialized. Therefore, the resulting value of sum (on the left side) is that arbitrary number plus square.
Simply add a sum = 0 statement like you have for count and square already.
Right off the bat, you do not initialize 'sum' to anything.
edit: A cleaned up version, though depending on compiler, you might need to enforce C99 mode, otherwise older compilers might not support initial declarations in the for loop.
#include <stdio.h>
int main()
{
const int COUNT_MAX = 10;
int sum = 0;
for ( int i = 1; i <= COUNT_MAX; ++i )
{
sum += i*i;
}
printf("The sum of squares from 1 to 10 is: %d\n", sum);
return 0;
}
Initialize sum with 0, otherwise it contains arbitrary data:
sum = 0;
See: http://codepad.org/e8pziVHm
sum is not initialized
You should do :
sum=0;
and remove
square=0;