atof ("0") возвращает 2 в переменной с плавающей точкой - PullRequest
0 голосов
/ 18 января 2019

Я пишу c встроенным на STM32F437VI. В какой-то момент мне нужно проанализировать некоторые строки, содержащие числа, как числа с плавающей запятой. Я использую atof, и он всегда работает с правильным результатом, за исключением одного странного случая. Если строка равна 0 или 0,0, это дает 2.

Я включил stdlib.h и даже попытался (float) atof () в typecast, но по какой-то странной причине переменная float всегда имеет значение 2 из операции atof ("0"), а двойное значение имеет правильный 0. Почему это происходит? Спасибо всем заранее.

#include "stdio.h"
#include "stdlib.h"

int main(void)
{
    char test[] = "0";
    float val1;
    double val2;

    val1 = atof(test);
    val2 = atof(test);

    return 0;
}

Я ожидаю, что явный результат 0 для переменной с плавающей точкой также будет фиксированным значением 2.

UPDATE : Этот раздел кода является частью гораздо более крупного проекта, и нет смысла разрабатывать проект. У меня есть пользовательский Makefile с опцией LDFLAG

"-mfloat-abi=hard -mfpu=fpv4-sp-d16 -u _printf_float".

Может ли это повлиять на эту проблему?

Что касается примера MCV, в main.c у меня есть фрагмент кода выше, и я получил упомянутые результаты. Кто-нибудь может вспомнить, почему atof () ведет себя так? Конечно, я также использовал онлайн-компилятор c с точно таким же кодом, и результат, конечно, равен 0. Я думаю, что если что-то было очень-очень неправильно с библиотекой stdlib, то atof () не будет работать и для всех других случаев. , Но он завершается ошибкой только для «0» и только с результатом 2, присвоенным переменной с плавающей запятой.

Я наблюдаю за переменными в реальном времени с помощью программного обеспечения отладчика Ozone. Может ли быть причина в использовании реализации с плавающей запятой на STM32F4 mcu? Отсутствует параметр в пользовательском Makefile или что-то в этом роде?

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Похоже, причина вашей проблемы в обновленном тексте вопроса:

ОБНОВЛЕНИЕ : Этот раздел кода является частью гораздо более крупного проекта, и нет смысла детально разрабатывать проект. У меня есть пользовательский Makefile с опцией LDFLAG

"-mfloat-abi=hard -mfpu=fpv4-sp-d16 -u _printf_float".

Предполагая, что эти параметры являются изменениями по сравнению со значениями по умолчанию, вы говорите компилятору генерировать код для другого ABI из экосистемы библиотеки вашей инструментальной цепочки. Код, сгенерированный для main, ожидает результата atof в регистре с плавающей запятой, но atof использует стандартный ABI, который передает аргументы с плавающей запятой и возвращаемые значения в регистрах общего назначения. Таким образом, main просто читает все ненужное, оставленное в регистрах с плавающей запятой, используемых для возвращаемых значений.

Посмотрите, исчезнет ли ваша проблема, если вы удалите -mfloat-abi=hard. Если это так, вы, вероятно, нашли свою проблему. Вам нужно либо создать набор инструментов и библиотек для ABI на жестком диске, либо придерживаться принятого по умолчанию соглашения о вызовах не на жестком диске.

0 голосов
/ 18 января 2019

Во-первых, в вашем вопросе отсутствует пример Минимальный, Полный и Проверяемый .

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    char test[] = "0";
    float val1;
    double val2;

    val1 = atof(test);
    printf("%f\n", val1);

    val2 = atof(test);
    printf("%f\n", val2);
}

Выход:

0.000000
0.000000

<°))) <() </p>

Или ваша стандартная реализация библиотеки - fubar.

...