1

我有一些使用 strtod(...) 将 ASCII 字符串转换为双精度的 C 代码。该程序已针对 x86(调试)、ARM 和 PowerPC(嵌入式目标系统)进行编译。ARM 板实际上是一个运行 Debian 的 BeagleBoard xM,可用于它。

我发现 strtod() 不能在 ARM / Debian 系统上正确转换值。事实上,我尝试的所有值都是 0.000。

为了演示,我编写了以下非常简单的测试程序:

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

int main(const int argc, const char **argv)
  {
  const char myString[] = "123 ";
  char *myEnd1 = NULL;
  char *myEnd2 = NULL;

  float  fValue = 0;
  double dValue = 0;

  dValue = atof(myString);

  printf(   "Using atof():\n"
            " String:  %s\n"
            " Double:  %lf\n",
             myString,
             dValue                           );

  fValue = strtof(myString, &myEnd1);
  dValue = strtod(myString, &myEnd2);

  printf(   "Using strtof() / strtod():\n"
            " String:  %s\n"
            " Float:   %f (%d)\n"
            " Double:  %lf (%d)\n",
            myString,
            fValue, (myEnd1 - myString),
            dValue, (myEnd2 - myString)             );

  return 0;
  }

所有这些都是在运行 Ubuntu 的 x86 PC 上编译的(实际上是在虚拟机中)。我有用于 PowerPC 和 ARM 编译的交叉编译器工具链。

在 x86 和 PowerPC 系统上,输出符合预期,即:

Using atof():
 String:  123 
 Double:  123.000000
Using strtof() / strtod():
 String:  123 
 Float:   123.000000 (3)
 Double:  123.000000 (3)

然而,当在 BeagleBoard 上运行时,我得到了这个:

Using atof():
 String:  123
 Double:  0.000000
Using strtof() / strtod():
 String:  123
 Float:   -0.372039 (3)
 Double:  0.000000 (3)

啊???我错过了什么愚蠢的事情吗?请注意,“myEnd”指针只是用来显示 strtod() 和 strtof() 确实找到了第一个非数字字符,因此找到了数字的结尾。他们在两种情况下都报告了数字中正确的字符数(3),但转换后的值是错误的。我不认为这是一个语言环境问题,因为没有小数点可以混淆。

编辑:

我刚刚使用“-static”选项重新编译了测试程序。当然,这使二进制文件变得更大,但现在它可以在目标 ARM 平台上正常工作。

我对图书馆的工作方式有点模糊。另外,我不记得我是如何构建我的交叉编译器工具链的。它可能不是从与实际安装在目标板上的 Debian Linux 相同的源构建的。

那么,atof() 等莫名其妙的行为是否意味着动态链接的可执行文件“预期”的库与系统上的实际库不同?我很惊讶这并没有导致更严重的问题。我们已经运行这个系统一年了,到目前为止,这是我们遇到的唯一一个奇怪的错误。

4

0 回答 0