【问题标题】:atof("0") returns 2 in float variableatof("0") 在浮点变量中返回 2
【发布时间】:2019-01-18 11:10:59
【问题描述】:

我写c嵌入在STM32F437VI上。在某些时候,我需要将一些包含数字的字符串解析为浮点数。我使用 atof 并且它总是以正确的结果工作,除了这个奇怪的情况。如果字符串为 0 或 0.0,则为 2。

我已经包含了 stdlib.h 甚至尝试 (float)atof() 进行类型转换,但由于一些奇怪的原因,float 变量始终具有来自 atof("0") 操作的值 2,而双精度值具有正确 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 值。

更新: 此代码部分是一个更大项目的一部分,没有必要详细说明该项目。我有带有 LDFLAG 选项的自定义 Makefile

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

这会影响这个问题吗?

就 MCV 示例而言,在 main.c 中我有上面的代码部分,我得到了提到的结果。 谁能想到 atof() 以这种方式表现的任何原因? 当然,我也使用过在线 c 编译器以及完全相同的代码,结果当然是 0。我想如果 stdlib 库出了什么问题,那么 atof() 也不适用于所有其他情况.但它仅对“0”失败,并且仅将结果 2 分配给 float 变量。

我使用 Ozone 调试器软件实时观察变量。 原因可能是使用了 STM32F4 单片机上的浮点实现吗?自定义 Makefile 中缺少参数或类似的东西?

【问题讨论】:

  • 使用您显示的代码,我们将无法复制您的问题。请尝试创建minimal reproducible example 向我们展示。
  • 您的工具链有可配置的浮点​​支持吗?此外,一些工具链允许禁用scanf 库函数的更复杂的功能,并且还可能影响ato*strto* 函数。
  • “我的代码太大了,无法在此处显示”的答案是 MCVE。 “太秘密”的答案是 MCVE。如果您只显示您猜测问题所在的代码行,但您自己没有找到它,那么很可能,错误在其他地方。制作 MCVE 以确保您和我们关注的是同一件事。如果我们无法重现它,那么是时候讨论编译器版本和环境的其他属性了。阅读 Some 提供的 MCVE 链接并将该概念应用于您的代码。在没有 MCVE 的情况下询问感知到的不当行为是题外话。
  • 如果您显示的内容足以让您为您复制问题,则将其放入main 函数中,添加头文件,并使其完整。然后告诉我们这是复制问题的最少代码(当然要确保您真的可以使用该程序复制它),并添加有关构建和运行设置和环境的所有详细信息。
  • 您的新代码不使用atof 返回的值。编译器可以优化变量分配。调试器可能没有显示真正的价值。您应该尝试打印结果并查看结果。

标签: c embedded stm32f4 atof


【解决方案1】:

首先,您的问题缺少Minimal, Complete, and Verifiable example

#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

或者你的标准库实现是 fubar。

【讨论】:

    【解决方案2】:

    您的问题的原因似乎在更新的问题文本中:

    更新:此代码部分是一个更大项目的一部分,没有必要详细说明该项目。我有带有 LDFLAG 选项的自定义 Makefile

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

    假设这些选项是更改而不是默认值,您所做的是告诉编译器从您的工具链的库生态系统中为不同的 ABI 生成代码。为main 生成的代码需要atof 在浮点寄存器中的结果,但atof 使用标准ABI,它在通用寄存器中传递浮点参数和返回值。因此,main 只是读取恰好留在用于返回值的浮点寄存器中的任何垃圾。

    如果您删除 -mfloat-abi=hard,请查看您的问题是否会消失。如果是这样,您可能已经发现了您的问题。您需要为 hardfloat ABI 构建工具链和库,或者坚持使用默认的非 hardfloat 调用约定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-14
      • 1970-01-01
      • 1970-01-01
      • 2019-03-16
      • 1970-01-01
      • 1970-01-01
      • 2017-04-22
      相关资源
      最近更新 更多