Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

C Data Types and Operands

Posted on 2003-12-08
6
Medium Priority
?
1,639 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
6 Comments
 
LVL 46

Expert Comment

by:Kent Olsen
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 46

Expert Comment

by:Kent Olsen
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 

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 46

Accepted Solution

by:
Kent Olsen earned 500 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

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
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…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.

610 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