Sunday, March 9, 2008

[Programming] Type casting problem in function's argument

Recently someone asked a question of C programming on a discussion board: he has some codes which handle a fixed point array by passing the name of the array to a function, for example:


/** Code 1 */
// declaration of the function
void f(int *pt);

// an array of fixed point integer
int A[10];

// call the function
f(A);




The above codes work successfully. Now he tries to extend the code to a floating point array, as follows:

double B[10];
f((int*)B);

The compiler didn't complain any error, but the output result is something weird. For example, run the following codes on gcc or visual c, you suppose to get output as 3, but the result is -266631570,



/** Code 2 */
#include <stdio.h>
void test_fun(int* px);
int main()
{
double a[10];

a[0] = 3.14159;
test_fun((int*)a);
return 0;
}

void test_fun(int *px)
{
printf("%d\n", *px);
}







We all know that we can type-cast a double variable to an integer variable like this:




/** Code 3 */
double d=3.14;
int c;
c=(int)d;




And we can pass an array to a function by the array's name if they are in the same type (as the above code 1). But why cannot we do the similar thing for passing a floating point array's name to a funciton which accepts fixed point variables?

The answer to this question is: floating point and fixed point numbers are stored in different formats. For floating point number, it conforms with IEEE754. For example, for a 32-bit computer, a single-precision binary floating point number is stored in the format of sign(1 bit) + exponent (8 bits) + fraction (23 bits). So if you simply pass the array's name of floating point numbers as function's argument to an array that accommodates fixed point numbers, the function will read the 32-bit floating point number in fixed point format. The compiler doesn't complain because, yes, you can read it. But the result cannot be what you expect.

The solution to this question may be: 1) cast each element of the floating point array to a fixed point array first, then call the function; 2) re-write the function to support floating point, such as using templates...

No comments: