The program should read 5 numbers from the user. Then it has to draw 5 'lines' according to the rate of this numbers. At the biggest number it has to draw 20 ' * '-s and for every other number it has to draw less ' * '-s in proportion to the biggest number.
There's a program which can check if my code is correct, and I tried a lot of things to make it work, but I always got bad result (right side on the picture). Then I was checking the solution of similar exercises and I found that the only difference is that, in the soutions there's a dot after the defined number
#define SEGMENT 20.
And when I changed just this one thing in my code it worked correctly (left side on the picture). Can someone explain why does it make such a huge difference and why it's working without dot too with some inputs? Here's the full code:
#include <stdio.h>
#define PCS 5
#define SEGMENT 20
//The only difference in the line above
//#define SEGMENT 20.
int main(void) {
double nums[PCS];
int max;
//Reding the five numbers and finding the biggest value
for(int i = 0; i < PCS; i++) {
scanf("%lf", &nums[i]);
if(i == 0 || max < nums[i]) {
max = nums[i];
}
}
//Calcualte the rate for the lines
double rate = SEGMENT / max;
//Print the lines
for(int i = 0; i < PCS; i++) {
for(int j = 0; j < (int)(nums[i]*rate); j++) {
printf("*");
}
printf("\n");
}
return 0;
}
In context of this statement
double rate = SEGMENT / max;
20
is an integer. Hence the expression 20 / max
is also an integer with remainder dropped before being assigned to rate
20.
is the same as 20.0
- it's a floating point real value. Hence, 20.0 / max
gets evaluated as a real number (with max
getting effectively promoted from integer to float before the division operation is applied). And the result of that expression is directly assigned to rate
without any rounding.
If it helps, you can avoid the floating point computation (and all the weirdness that goes with fp) by doing integer math and having the division operation performed as the last step of your calculation.
That is, instead of this:
#define SEGMENT 20.0
...
double rate = SEGMENT / max;
...
for(int j = 0; j < (int)(nums[i]*rate); j++) {
This:
#define SEGMENT 20
...
for(int j = 0; j < (int)(nums[i]*SEGMENT)/max; j++) {
This keeps your math in the integer space and should still work. (Disclaimer: nums
is still an array of double, so the expression (nums[i]*20)/max
is still a floating point value, but it's not going to incur a rounding error.