Solved

C Data Types and Operands

Posted on 2003-12-08
6
1,570 Views
Last Modified: 2008-02-01
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
0
Comment
Question by:mkimsal
  • 3
  • 2
6 Comments
 
LVL 45

Expert Comment

by:Kdo
ID: 9900394

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
0
 
LVL 1

Expert Comment

by:travd
ID: 9900842
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?
0
 
LVL 45

Expert Comment

by:Kdo
ID: 9901060

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

0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 

Author Comment

by:mkimsal
ID: 9901474
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!
0
 
LVL 45

Accepted Solution

by:
Kdo earned 125 total points
ID: 9901525
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;

main()

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)]));



Kent
0
 

Author Comment

by:mkimsal
ID: 9912964
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.  
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now