I am doing the cs50 course and I am in week 4 (Memory) and I am doing the homework.
this is my code for grayscale
:
void grayscale(int height, int width, RGBTRIPLE image[height][width])
{
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
uint8_t Red = image[i][j].rgbtRed;
uint8_t Green = image[i][j].rgbtGreen;
uint8_t Blue = image[i][j].rgbtBlue;
uint8_t avg = (Red + Green + Blue) / 3;
image[i][j].rgbtRed = avg;
image[i][j].rgbtGreen = avg;
image[i][j].rgbtBlue = avg;
}
}
return;
}
Can you explain the 27 not 28 and most importantly this: expected "20 20 20\n50 5...", not "20 20 20\n50 5..."
If you for example have the channel values 5
, 4
, and 8
, then the sum of these values is 17
and the average is 5.666667
.
However, in C, when you write ( 5 + 4 + 8 ) / 3
, then this is equivalent to 17 / 3
and will perform an integer division (Euclidean division), which means the result of the division is 5
with a remainder of 2
. Therefore, the expression 17 / 3
will evaluate to 5
and the expression 17 % 3
will evaluate to 2
(which is the remainder).
An integer division (euclidean division) is not the kind of division that you need for this assignment. Rather, the assignment wants you to perform a division with a fractional part, so the result is 5.666667
, and then this result should be rounded to the nearest integer. Therefore, the result should be 6
in this example.
In C, if both arguments of the /
operator are of an integer type, then an integer division is performed. If at least one of the arguments is of a floating-point type (such as float
or double
), then the other argument is converted to the floating-point type and a floating-point division is performed instead of an integer division, so that the result is a floating-point value with a fractional part.
Therefore, the easiest way to enforce a floating-point division is to change one of the arguments to a floating-point type. This can be done by changing the line
uint8_t avg = (Red + Green + Blue) / 3;
to:
uint8_t avg = (Red + Green + Blue) / 3.0;
However, this still won't work, because assigning the value 5.666667
to an integer data type will convert that value to 5
. Instead, the result should be rounded to the nearest integer value, which is 6
. For this, you can use the functions round
or lround
:
uint8_t avg = round((Red + Green + Blue) / 3.0);