(arm-elf-gcc and friends) Bug in floating point conversion/formatting ... ?

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
Lately I have had a lot of trouble with the behaviour in a program I'm
working on. Finally now I'm able to reproduce some weird behaviour wrt.
floating point conversion. See the code snippet below which is the true
code. The "0" prefix comes from the send_n function.

I am running the arm-elf-gcc toolchain, uC is an Atmel AT91R40807:

arm-elf-gcc
    ver 2.96
arm-elf-as
arm-elf-ld
arm-elf-objcopy
    ver 2.10


(Sorry, I don't know which library versions I use, and also don't know
how to find it out. Please advise.)

When I run the code below the following gets printed

0   Check :   39.37
0   Check : 39.374996
0   Check :   30.00
0   Check : 39.375000
0   Check :   39.38
0   Check : 39.375004

If I change the formatting from %7.2f to %7.3f everything works like a
charm, and the following is printed on the serial terminal

0   Check :  39.375
0   Check : 39.374996
0   Check :  39.375
0   Check : 39.375000
0   Check :  39.375
0   Check : 39.375004

I have had no luck googling for a solution/explanation, but of course, I
might have been looking in the wrong direction.

All and any suggestions are welcome. Also, please don't hesitate to ask
for further information.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void showfloatbug(int n)
{
   union longfloat {
     float flow;
     unsigned long l;
   } u;

   u.l = 0x421d7fff;
   snprintf(dbuf,sizeof(dbuf),"   Check : %7.2f",u.flow);
   send_n(n,dbuf);
   snprintf(dbuf,sizeof(dbuf),"   Check : %f",u.flow);
   send_n(n,dbuf);

   u.l = 0x421d8000;
   snprintf(dbuf,sizeof(dbuf),"   Check : %7.2f",u.flow);
   send_n(n,dbuf);
   snprintf(dbuf,sizeof(dbuf),"   Check : %f",u.flow);
   send_n(n,dbuf);

   u.l = 0x421d8001;
   snprintf(dbuf,sizeof(dbuf),"   Check : %7.2f",u.flow);
   send_n(n,dbuf);
   snprintf(dbuf,sizeof(dbuf),"   Check : %f",u.flow);
   send_n(n,dbuf);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

BR,
--
Torbjørn Heltne
AM Elektronikk AS


Re: (arm-elf-gcc and friends) Bug in floating point conversion/formatting... ?

Quoted text here. Click to load it

I just want to point out where the problem is visible,
in the 3rd "Check" line here, where 30.00 is printed instead of 39.38.

TIA,
--
Torbjørn Heltne
AM Elektronikk AS

Re: (arm-elf-gcc and friends) Bug in floating point conversion/formatting ... ?
Quoted text here. Click to load it

This is a library problem - the print formatter conversion is there. As
you're feeding in the float patterns in hex, the compiler has little to
do with them. To be sure, check the generated assembly code with the -S
switch to the GCC.

Your compiler is pretty old - the ARM code generation was completely
rebuilt for GCC 3.x, please update if possible. The ELF support on
2.96 was kludged on to provide a minimal support for ARM-based
Linux versions.

Also, version 2.96 is *not* a genuine GCC version at all, it is a
Red Hat special known to have problems. For details, have a look
at the GNU pages <http://www.gnu.org/ .

HTH

Tauno Voipio
tauno voipio @ iki fi


Re: (arm-elf-gcc and friends) Bug in floating point conversion/formatting... ?


Quoted text here. Click to load it

I just wrote in my reply to CBFalconer that my original posting was
somewhat ...unclear. Please take a look at my updated posting.

Quoted text here. Click to load it

True. The toolchain I use is a bit old.


--
Torbjørn Heltne
AM Elektronikk AS


Re: (arm-elf-gcc and friends) Bug in floating point conversion/formatting... ?
Quoted text here. Click to load it
... snip ...
Quoted text here. Click to load it

While it is not impossible that a system bug exists, your code is
doubly flawed.  First, you cannot legally extract a value from a
union in a different form from that you put in.

I am ignoring the undefined send() and dbuf above, I assume they
have some meaning to you.  I am also ignoring the lack of suitable
#includes to define snprintf, etc.

The legitimate way to access the bytes of something is via an
unsigned char * pointer.  The reverse mechanism MAY work, in fact
usually will, but is not guaranteed.

char getbyte(void *thingptr, int which)
{
   unsigned char *p = thingptr;

   return p[which];
}

Something that may well be happening to you is that floats and
integers are stored in different registers, have different
internal lengths, etc.  You are not accessing what you think you
are.  You can also create:

void putbyte(void *thingptr, int which, const unsigned char ch)
{
   unsigned char *p = thingptr;

   p[which] = ch;
}

Now you could have your system above:

  int           i, lgh;
  unsigned long l;
  float         f;

  l = 0L;
  f = 39.37;

  for (i = 0; i < sizeof f; i++)
     putbyte(&f, i, (l >> (i * 8)) & 0xff);

where the 8 and 0xff are only valid if CHAR_BIT is 8.  This also
has the (not guaranteed) assumption that sizeof(long) ==
sizeof(float).  It should avoid peculiarities to do with actual
implementation details.  Note the &f to start with a pointer.  The
use of void* types will assure the correct transformations.

The main point is: Don't take shortcuts around the standard.  If
fully standards compliant code fails, you have a right to
complain, but not before.

--
Chuck F ( snipped-for-privacy@yahoo.com) ( snipped-for-privacy@worldnet.att.net)
   Available for consulting/temporary embedded and systems.
We've slightly trimmed the long signature. Click to see the full one.
Re: (arm-elf-gcc and friends) Bug in floating point conversion/formatting... ?


Quoted text here. Click to load it

I realize that my original posting was not to the point(!) describing
the problem I'm facing. Sorry about that. I just posted an updated
description which I hope is a little bit better.

--
Torbjørn Heltne
AM Elektronikk AS


Re: (arm-elf-gcc and friends) Bug in floating point conversion/formatting... ?

(Something that I realize is pretty easy to misunderstand)
:-)

Let me re-visualize the actual problem this way:

~~~~~~
char dbuf[81];

void showfloatbug(int n)
{
   float f = 39.375;
   sprintf(dbuf,"   Check : %7.2f",f);
   /*Some code here to send dbuf on the serial port*/
   sprintf(dbuf,"   Check : %7.3f",f);
   /*Some code here to send dbuf on the serial port*/
}
~~~~~~

This is printed on my terminal:

    Check :   30.00
    Check :  39.375

--
Torbjørn Heltne
AM Elektronikk AS


Re: (arm-elf-gcc and friends) Bug in floating point conversion/formatting... ?


TorbjF8%rn Heltne schrieb:
Quoted text here. Click to load it
Hello,

it looks like a bug in the used <stdio.h> library.
You could try the types e or g instead of f, but the same bug might be20%
involved there too.
sprintf(dbuf,"   Check : %7.2e",f);
sprintf(dbuf,"   Check : %7.2g",f);

Bye


Re: (arm-elf-gcc and friends) Bug in floating point conversion/formatting... ?
Quoted text here. Click to load it

We are still pointing to an obvious bug in the run-time
print formatter in the library.

Tauno Voipio
tauno voipio @ iki fi

PS. If you ever can, get rid of the GCC version 2.96.

TV



Re: (arm-elf-gcc and friends) Bug in floating point conversion/formatting... ?
Hello,

i just tried it out on LPC2106 with arm-elf-gcc version 3.3.2 and it gives
me the following result:
(slighty modified your code, haven't used it in a subroutine, but shouldn't
matter)

   Check :   39.38   Check :  39.375

So it look like to work !

Greetings,

         Martin


Quoted text here. Click to load it



Re: (arm-elf-gcc and friends) Bug in floating point conversion/formatting... ?

I have received a lot of useful input. Thank you to all!

I have now set up a newer toolchain by following these instructions:
<url: http://sources.redhat.com/ecos/build-toolchain.html

The printf(....) problems I described are history.

BR,
--
Torbjørn Heltne
AM Elektronikk AS


Site Timeline