Link to home
Start Free TrialLog in
Avatar of mkimsal
mkimsal

asked on

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.

Thanks,
Matt
Avatar of Kent Olsen
Kent Olsen
Flag of United States of America image


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.

Kent
Avatar of travd
travd

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;

or

*(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?

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.

BTW,

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

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


Kent

Avatar of mkimsal

ASKER

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;

main()

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!
ASKER CERTIFIED SOLUTION
Avatar of Kent Olsen
Kent Olsen
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of mkimsal

ASKER

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.