Click here to Skip to main content
15,888,286 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello. I am currently trying to copy an array of ‘double’ values into an array of “unsigned char”.

I have checked my code to know that the expected values in 2 dimensional double arrays, sig_out_imageR, sig_out_imageG and sig_out_imageB are correct (values were written to a file).

I am currently trying to get these values into a 1 dimensional array of unsigned char for later processing. However, the values are incorrect (normally down by 1). For example, instead of the value being 36, it’s 35, or instead of the value being 204, it’s 203.

I have tried casting the double to an unsigned char in hope of preventing loss of data but this clearly hasn’t helped.

I am using Visual Studio 2010. Would appreciate to learn how to fix this error, thank you.

This is the main conversion part:

C++
//put RGB from 2D array contents back into a 1D array
unsigned char* array_1D_RGB_FFT;
array_1D_RGB_FFT = new unsigned char[height*width*bytesPerPixel];
if (array_1D_RGB_FFT == NULL) return 0;  // return if memory not allocated 

ofstream RGBdata1D;
RGBdata1D.open("RGBdata1D.txt");

int offset = 0;
int counter = 0;
int bytesPerPixel = 3;
	
for (int j = 0; j<height; j++)  // traverse height (or rows) 
{
	offset = width * bytesPerPixel * j;
	for (int i = 0; i<width*bytesPerPixel; i+= bytesPerPixel) // width  
	{
		array_1D_RGB_FFT[offset + i + 0] = static_cast<unsigned char>(sig_out_imageB[j][counter]);
		array_1D_RGB_FFT[offset + i + 1] = static_cast<unsigned char>(sig_out_imageG[j][counter]);
		array_1D_RGB_FFT[offset + i + 2] = static_cast<unsigned char>(sig_out_imageR[j][counter]);

RGBdata1D << "B: " <<(int)array_1D_RGB_FFT[offset + i + 0]
	<< " G: " <<(int)array_1D_RGB_FFT[offset + i + 1]
	<< " R: " <<(int)array_1D_RGB_FFT[offset + i + 2]<< endl;

++counter;

	}
counter = 0;
}

RGBdata1D << "count of pixels: " <<c<< endl;
RGBdata1D.close();
Posted

1 solution

It seems that your input values are not integers (have decimal places = digits after the decimal mark). When casting such floating point values, the decimal places are ignored. To implement rounding to nearest, add 0.5 before casting:
C++
int val = static_cast<int>(someDoubleVal + 0.5);


The next problem is the possible loss of data. The integer part of double floating point numbers may be much larger than the number of digits that can be held by an unsigned char. This will be complained by the compiler (as error or warning depending on the compiler settings). The simplest approach to avoid the warning is using classic C casting:
C++
unsigned char val = (unsigned char)(someDoubleVal + 0.5);

But this should be only used when you are sure that the input values are always in the range of 0 to 255. With RGB values, you might just limit the values using a function:
C++
unsigned char doubleToUChar(double val)
{
    unsigned char uc = 0;
    if (val >= 255.)
        uc = 255;
    else if (val > 0)
        uc = (unsigned char)(val + 0.5);
    return uc;
}
 
Share this answer
 
v3
Comments
binaryoffset 16-Oct-15 9:33am    
Thank you! You've very clearly explained the problem at hand and the solution. It works now.
Jochen Arndt 16-Oct-15 9:59am    
Thank you for your reply and accepting the solution.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900