This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

atof not working in LPC 1788

I am writing Programm using LPC1788, with RTX os .
Through out Programm i have used atof function many times, but now if m adding new atof function, it is not working Properly, even i dont get any error while compilation or debugging.

Alo if i am adding manual calculation for float copnversion , still same issue occured , converted float value is incorrect.

i got converted float value is incorrect why such issue occured , i didnt get it..

currently my stack size 0x0000 1000

and heap size : 0x0000 0500

and OS stack size: 500

someone plz help me out.

/**************************************************
Function: calculate_float_value
Comment: This use to return a float value for buffer like "000.00".
Arguments: The buffer name & the no of digit in the buffer including decimal point
Returns: The absolute decimal point value.
***************************************************/
float calculate_float_value(char* temp_buff,uint8_t num_digit)
{ uint8_t i; uint32_t return_value,temp; //temp used only when it is 7-digit. uint32_t deci_point; float result; char store_value[10];

for(i=0;i<num_digit;i++) { store_value[i] = *temp_buff++; }

if(num_digit==5) { return_value = ( ( ((store_value[0] & 0x0f)*1000) + ((store_value[2] & 0x0f)*100) +((store_value[3] & 0x0f)*10)+ (store_value[4] & 0x0f) )/1000); deci_point = ( ( ((store_value[0] & 0x0f)*1000) + ((store_value[2] & 0x0f)*100) +((store_value[3] & 0x0f)*10)+ (store_value[4] & 0x0f) )%1000);

result = (float)return_value + ((float)deci_point/1000);

}

if(num_digit==6) { return_value = 0; return_value = (store_value[0] & 0x0f); return_value *= 10000; return_value += ((store_value[1] & 0x0f)*1000); return_value += ((store_value[3] & 0x0f)*100); return_value += ((store_value[4] & 0x0f)*10); return_value += (store_value[5] & 0x0f);

deci_point = return_value; return_value /= 1000; deci_point %= 1000;

result = (float)return_value + ((float)deci_point/1000); }

if(num_digit==7) { return_value = 0; return_value = ((store_value[0] & 0x0f)*100)+((store_value[1] & 0x0f)*10)+((store_value[2] & 0x0f)*0x0f); deci_point = ((store_value[4] & 0x0f)*100) +((store_value[5] & 0x0f)*10) +(store_value[6] & 0x0f);

result = (float)return_value + ((float)deci_point/1000); }

if(num_digit==8) { return_value = 0; return_value = ((store_value[0] & 0x0f)*1000)+((store_value[1] & 0x0f)*100)+((store_value[2] & 0x0f)*10)+(store_value[3] & 0x0f); deci_point = ((store_value[5] & 0x0f)*100) +((store_value[6] & 0x0f)*10) +(store_value[7] & 0x0f);

result = (float)return_value + ((float)deci_point/1000); }

return((float)result);
} /************************************************************/

Parents
  • Sorry but you have
    1) Posted code without reading the instructions for how to tag the code so it gets readable (didn't you spot the text directly above the message input box?)
    2) Written quite complex code with lots of hard-coded rules that aren't really needed.
    3) Failed to write a proper description of exactly what you expect the result should be of your function - including actual example data.
    4) You talk about floating point but make use of / and % which are more related to fixed-point numbers.
    5) You seem to have missed the ability to loop through digits instead of hard-code logic depending on number of characters.
    6) You use temporary variables for some arbitrary reason.

    Note that

    (float)return_value + ((float)deci_point/1000);
    


    is a quite interesting construct.

    The value 123.456 can be converted to the fixed-point integer 123456 with three implied decimals. And this value can then be converted to a floating point value with:

    ((float)fp)/1000;
    


    or

    fp*0.001;
    

    What do you think your construct would do if the input number is negative? Should you then add or subtract your fractional part?

    An interesting thing here is why you have floating point all over your program? Most embedded programs runs much faster if written with fixed-point logic instead of floating point, since lots of microcontrollers doesn't have any floating point support and so requires all floating point calculations to be emulated by a rather large emulation library. Another advantage with fixed point is the ability to work with huge precisions - it's possible to use a big-number library and work with hundreds of digits without losing important value digits.

Reply
  • Sorry but you have
    1) Posted code without reading the instructions for how to tag the code so it gets readable (didn't you spot the text directly above the message input box?)
    2) Written quite complex code with lots of hard-coded rules that aren't really needed.
    3) Failed to write a proper description of exactly what you expect the result should be of your function - including actual example data.
    4) You talk about floating point but make use of / and % which are more related to fixed-point numbers.
    5) You seem to have missed the ability to loop through digits instead of hard-code logic depending on number of characters.
    6) You use temporary variables for some arbitrary reason.

    Note that

    (float)return_value + ((float)deci_point/1000);
    


    is a quite interesting construct.

    The value 123.456 can be converted to the fixed-point integer 123456 with three implied decimals. And this value can then be converted to a floating point value with:

    ((float)fp)/1000;
    


    or

    fp*0.001;
    

    What do you think your construct would do if the input number is negative? Should you then add or subtract your fractional part?

    An interesting thing here is why you have floating point all over your program? Most embedded programs runs much faster if written with fixed-point logic instead of floating point, since lots of microcontrollers doesn't have any floating point support and so requires all floating point calculations to be emulated by a rather large emulation library. Another advantage with fixed point is the ability to work with huge precisions - it's possible to use a big-number library and work with hundreds of digits without losing important value digits.

Children
  • Thanks for fast response...
    hoping for the best..

    whatever code i had posted on thred is used for manual calculation for float conversion.

    because atof library function is not working... why atof function is not working, that i dont understand,could please answer me why atof function gives me incorrect value , if i am converting asccii buffer value into float usign atof...actully the same library function i have used throughout same programm in different functions and different files too...but nowonwards if i m adding new atof function in code .. it gives me incorrect value...please guide me...

  • No, I have no idea why your atof() doesn't work.

    But that function you posted is an excellent example of how you can improve as a programmer by thinking a bit about how you write your code.

    You have a huge amount of hardcoded assumptions - but have not documented a single assumption in the function header.

    What about code like (untested written on-the-fly):

    int64_t val = 0,prev = 0;
    float scale = 1.0;
    
    if (*s == '-') {
        scale = -1.0;
        s++;
    }
    if (*s < '0' || *S > '9') {
        fail_invalid number();
    }
    while (*s >= '0' && *s <= '9') {
        val = 10*val + *s-'0';
        if (val < prev) {
            fail_overflow();
        }
        prev = val;
        s++;
    }
    if (*s == '.') {
        s++;
        while (*s >= '0' && *s <= '9') {
            val = 10*val + *s-'0';
            if (val < prev) {
                fail_overflow();
            } else {
                scale *= 0.1;
            }
            s++;
        }
    }
    if (*s) {
        fail_extra_characters();
    }
    return val * scale;
    


    Suddenly not hard-coded to a fixed number of digits before the decimal point.
    And not hard-coded if there is a decimal point.
    And not hard-coded how many decimals after the decimal point.

    Assumptions? Yes, still a lot of them.
    - No support for 1.10E12
    - No support for a silly number of digits that that doesn't fit in a int64_t but can (with rounding) be represented in a float or double.
    - ...

    But thinking about limitations and possible algorithms really is quite important. And catching overflows/underflows or constructs that breaks the assumptions is quite important. It's too easy to destroy things or hurt people if running code that doesn't document and when possible test assumptions.