• C

C Data Types and Operands

I am actually working in MATLAB/Simulink, however, I need to create my own custom block, and I must use C code inside that block.  My problem arises as such...

I read into Matlab a 480x640 matrix of "uint8" data, which I subsequently convert to format "double" (double precision).  Simulink reads this matrix in and hands it to my custom C code.  

When Simulink reads in the data, I declare it as format "double"...Matlab double.  Which gets to the heart of my question.  Is Matlab's double the same as C's "double?"  I assume that they are, however, I am running into problems.

I have a very simple algorithm which computes the centroid of an object.  To do this, I must access the data in the matrix, and in certain instances multiply by integers.  

If I simply read the data from the matrix, I have no problems.  But when I try to multiply by an integer "i" or "j" (declared as "int" at beginning of code) my answers are way off.  I have tried declaring the variables "i" and "j" to "long", "unsigned long," and "double."  I have also tried changing the input matrix back to "uint8" data.  I get different answers with each combination of formats used.  

Thus I am not sure where to go.  When I declare the variables "i" and "j" as "double," the compiler tells me that I have
"operands of + have illegal types 'pointer to const double' and 'double'"

I have no idea what this means!  Why can't I declare "i" and "j" to be double?  FYI, "i" and "j" are variables which point to the current matrix location that I want to look at.  They are cycled between 0-479 and 0-679, respectively.

I hope all the info is here.  I appreciate any help anyone has to offer.

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Kent OlsenData Warehouse Architect / DBACommented:

Hi mkimsal,

The word "double" is reserved to C and has an explicit meaning.  If a variables is defined as:

double VarName;

then you can be sure that the variable conforms to C's understanding of what a double is.

If your variables are defined as a different type, you'll need to check the 'typedef' statements in your program and header files to see what data type is actually being used.

Can you give an example to you statement that, "my answers are way off".  Remember that precedence in C covers data types AND operator order!

char a, b, c, d, e, f;
float A, B, C, D, E, F;
int  j, k, l, m, n, o;

A = B * j;   /*  Will probably give you the answer that you want  */

A = j * B;  /* convers 'B' to an int, multiplies, and converts the answer to a float  */

In second example above, if j = 1000 and b = 1.999, the result will be 1000.0!

If you're data values are being truncated, it's probably due to on-the-fly data conversion due.

Wow, Kdo, I sure hope you don't work for NASA or anything.

This statement is wrong:
"Remember that precedence in C covers data types AND operator order!"

float A,B;
int j;

A = j*B;

This will NOT convert B into an integer and multiply.  Instead, both operands are "promoted" to a data type that is large enough to hold either.  In this case, both j and B are promoted to double (or perhaps float on a machine with 2-byte ints) and then the result is converted back into a float for assignment to A.

The result of the multiplication you suggest is in fact 1999, not 1000.  Try it.

As for your actual problem, you need to find out what type the variables coming in from matlab are.  Can you post some code that shows how you declare the array that you read from?  What header files do you need to include to have Simulink call your C code?  When you say you are able to "read the value from the matrix ok" - do you mean that you can read them and printf("%f", matix[i][j]) everything ok?

If you are using i, j to index an array (or a 2D array) they must be integral types.  You cannot use double types like:

double i,j;
matrix[i][j] = 1.5;


*(matrix + i) + j

This might be where you are getting the compiler error.  You must watch out for overflow - how big are the biggest numbers that will result during your calculations?
Kent OlsenData Warehouse Architect / DBACommented:

Hi travd,

Don't know where my brain was when I was typing that....  I'd like to claim that I was distracted by 'real' work, but that won't fly either...  :)

Apologies.  I was clearly off the mark here.


int i = 1;
float j = 1.999;
float result;

result = i * j;  Actually rounds UP to 2.000 on my system.  :)


The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

mkimsalAuthor Commented:
Thanks to both of you for the help.

I did not want to post any code before, but I suppose that I will now.  

I am only calling <stdio.h> and <math.h>.  As a matter of fact, I'm pretty sure I don't even need the stdio header.  Here is a part of the code I am using.
NOTE:  u0 is the input matrix.  It is not declared here, but in another part of a GUI function builder in Simulink (S-function builder).  Therefore, the end-result code (a C MEX-function (Matlab EXecutable)) DOES contain u0 in it.  It does recognize it as a matrix of the proper size and data type (either uint8 or double, whichever I choose it to be).  I am positive that u0 is being passed in as whichever of those I choose it to be (I've been changing it around to see if I can get it to work).

int i,j,object_X_center, object_Y_center;
int X_sum = 0, Y_sum = 0, z_total = 0, local_z = 0;


for (i=0; i<480; i++)
   for (j=0;j<680;j++)
       z_total = z_total + u0[i+(480*j)];

for (i=0; i<480; i++)
   for (j=0;j<680;j++)
       X_sum = X_sum + j*(u0[i+(480*j)]);

The two for loops are separate.  There is one more to compute Y_sum in the same manner as X_sum.  The computer returns z_total properly (verified as I have the same code in Matlab and that gives me the proper answer).  However, X_sum and Y_sum will not return the proper answers.  Depending on what data type I declare for u0, X_sum, and Y_sum, I can get answers anywhere from -113789 to 0 to 19for X_sum.  Y_sum usually keeps returning an answer like 173859322--close to what it should be but not right on--it should be about an order of magnitude larger.  There should be no reason for the return of a negative answer.  There are no negative numbers in the code, nor subtraction operators.  

I did try once to change my indexing variables (i,j) to double, and that is why I received the compile errors.  Thanks for clearing up that point, travd.

I appreciate the help so far!
Kent OlsenData Warehouse Architect / DBACommented:
Hi mkimsal,

There's every indication that you're simply overflowing the variable.  The negative result is a sure sign that the result has overflowed into the sign bit.

You can redefine all of the 'int' to 'unsigned int' or 'long'.  You can also try this:

int i,j,object_X_center, object_Y_center;

float X_sum = 0, Y_sum = 0, z_total = 0, local_z = 0;


for (i=0; i<480; i++)
   for (j=0;j<680;j++)
       z_total += (0.0  + u0[i+(480*j)]);

for (i=0; i<480; i++)
   for (j=0;j<680;j++)
       X_sum += (0.0 + j*(u0[i+(480*j)]));


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
mkimsalAuthor Commented:
One more comment on this,

This was basically the correct solution.  As stated earlier, the counter variables i and j should not be of format "double."  However, all the rest of the variables should be (or they could be "long," I suppose.)

What I was not trying was separating the variable declarations of i and j and all the rest of the variables in the top line.  I did not think that that made a difference, but it did.

Thanks for the help from everyone.  
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.