GNU C: atof(), strtof() and strtod() fail (Debian for BeagleBoard)

大兔子大兔子 提交于 2019-12-11 08:00:00

问题


I have some C code which converts an ASCII string to a double with strtod(...). The program gets compiled for x86 (debugging), ARM and PowerPC (embedded target systems). The ARM board is actually a BeagleBoard xM running the Debian which is available for it.

I've discovered that strtod() does not convert the values correctly on the ARM / Debian system. In fact all values I tried came out as 0.000.

To demonstrate, I wrote the following very simple test program:

#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;
  }

All were compiled on an x86 PC running Ubuntu (actually in a virtual machine). I have cross-compiler toolchains for PowerPC and ARM compilation.

On the x86 and PowerPC systems, the output is as expected, i.e.:

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

However, when run on the BeagleBoard, I get this:

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

Huh??? Did I miss something stupid? Note that the "myEnd" pointers are just there to show that strtod() and strtof() did find the first non-numeric character and therefore the end of the number. They report the correct number of characters in the number in both cases (3), yet the converted value is wrong. I don't think it's a locale problem as there is no decimal point to get confused about.

EDIT:

I just recompiled the test program with the option "-static". This made the binary much bigger, of course, but now it works correctly on the target ARM platform.

I'm a bit hazy on the way libraries work. Also, I can't remember exactly how I built my cross compiler toolchain. It was probably not built from the same source as the Debian Linux actually installed on the target board.

So, does the inexplicable behavior of atof(), etc, mean a library "expected" by the dynamically-linked executable is not the same as the actual library on the system? I'm surprised that this didn't cause worse problems. We've been running this system for a year, and so far this is the only strange bug we have encountered.

来源:https://stackoverflow.com/questions/25756939/gnu-c-atof-strtof-and-strtod-fail-debian-for-beagleboard

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!