Проблема в точности. A float
просто не очень точный. Чтобы пройти тесты, измените значение с float
на double
. Это можно увидеть, если вы запустите этот код:
float t = 123456789;
printf("%f\n", t);
Ваш код слишком сложен. Вот гораздо более удобное решение.
double StringToFloat(uint8_t *var)
{
// First check if negative. If it is, just step one step forward
// and treat the rest as a positive number. But remember the sign.
double sign = 1;
if(*var=='-') {
sign = -1;
var++;
}
// Read until either the string terminates or we hit a dot
uint32_t integer_part = 0;
while(*var != 0) {
if(*var == '.' || *var == ',') {
var++;
break;
}
integer_part = 10*integer_part + (*var - '0');
var++;
}
// If we hit the string terminator in previous loop, we will do so
// in the beginning of this loop too. If you think it makes things
// clearer, you can add the boolean found_comma_or_dot to explicitly
// skip this loop.
uint32_t decimal_part = 0;
uint32_t decimal_size = 0;
while(*var != 0) {
decimal_part = 10*decimal_part + (*var - '0');
var++;
decimal_size++;
}
return sign * (integer_part + decimal_part/pow(10, decimal_size));
}
Обратите внимание, что я изменил uint16_t
на uint32_t
, потому что я использую их по-другому. Если этот вариант не подходит для вас, вы можете изменить их на плавающий тип, но это может привести к потере точности.
Существуют причины для использования uint16_t
и float
, но выприходится жить с ограничениями. Так оно и есть.