ccontikicooja

Float Calculation in Cooja


I'm using RPL in Contiki 3.0 and I need to make some calculations where the results are float. But instead of giving me the result in float, it is only calculating the integer number for example: 5/2 = 2.0 instead of 2.5. How can I get the right answer? I can not print float or double in Contiki 3.0 so I'm using this code to convert float into a string:

    // Reverses a string 'str' of length 'len'
    void reverse(char* str, int len)
    {
        int i = 0, j = len - 1, temp;
        while (i < j) {
            temp = str[i];
            str[i] = str[j];
            str[j] = temp;
            i++;
            j--;
        }
    }

  
// Converts a given integer x to string str[]. 
// d is the number of digits required in the output. 
// If d is more than the number of digits in x, 
// then 0s are added at the beginning.
int intToStr(int x, char str[], int d)
{
    int i = 0;
    while (x) {
        str[i++] = (x % 10) + '0';
        x = x / 10;
    }
  
    // If number of digits required is more, then
    // add 0s at the beginning
    while (i < d)
        str[i++] = '0';
  
    reverse(str, i);
    str[i] = '\0';
    return i;
}
  
// Converts a floating-point/double number to a string.
void ftoa(float n, char* res, int afterpoint)
{
    // Extract integer part
    int ipart = (int)n;
  
    // Extract floating part
    float fpart = n - (float)ipart;
  
    // convert integer part to string
    int i = intToStr(ipart, res, 0);
  
    // check for display option after point
    if (afterpoint != 0) {
        res[i] = '.'; // add dot
  
        // Get the value of fraction part upto given no.
        // of points after dot. The third parameter 
        // is needed to handle cases like 233.007
        fpart = fpart * powf(10, afterpoint);
  
        intToStr((int)fpart, res + i + 1, afterpoint);
    }
}
  

I appreciate your help Thanks Hanin


Solution

  • If you want to print a number as a float, simply print the part before the floating point as an integer, print the dot, and then multiply the part after the floating point with a power of 10 and print it as another integer. For example, if you want to print 6 digits after the floating point, multiply the fractional part with 1000000.

    You will need a separate buffer to print the part after the floating point first - the first digit must be nonzero, so the safe option to pad the number with another digit e.g. "1" that you do not print. To do that, simply add the 1.0 to the fractional part before multiplying it.

    Here is the complete code:

    float f = 5.0 / 2;
    char fractional_part[10];
    sprintf(fractional_part, "%d", (int)((f - (int)f + 1.0) * 1000000));
    printf("%d.%s\n", (int)f, &fractional_part[1]); // prints "2.500000"