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);
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);
return((float)result); } /************************************************************/
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.