我有一些C代码,它使用strtod(...)将ASCII字符串转换为double。该程序针对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()等无法解释的行为是否意味着动态链接的可执行文件“期望”的库与系统上的实际库不同?我很惊讶这不会导致更糟糕的问题。我们已经运行了这个系统一年,到目前为止,这是我们遇到的唯一奇怪的错误。