This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Question for displaying floating point in eCOSaplication.


> when I do the following:
>
> printf("%f\n",0x40800000);
>
> // I got output as:
> 512.000000
>
> Is that right? I am expecting the output will be 4.00 but ??

I am assuming your querries are wrt eCos printf (but similar problems do exist
elsewhere too).

It all depends on many factors, what output you will get. And on eCos surely you
won't get what you expect in the mentioned case, the reason being mentioned
code-snippet from vfnprintf function --

packages/language/c/libc/stdio/current/src/output/vfnprintf.cxx
--------------------------------------------------------------
#ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT
             case 'e':
             case 'E':
             case 'f':
             case 'g':
             case 'G':
                      _double = va_arg(arg, double);
--------------------------------------------------------------

It is giving float/double same treatment (that could have been valid, had double
and float were of same size)

This code will always liftup sizeof(double) bytes from argument stack
irrespective of whether we want to print a float or double.

Though cvt function (further down in that file) also makes similar assumption,
but a small fix in vfnprintf

So it is not guaranteed what will you get in the example you are trying.

You are trying that example on Big-Endian architecture and coincidentally the
lower 32 bits of double turn out to be zero, thus giving you 512. had they not
been zero, you would have got something else as result.

On little endian architecture --
printf("%f\n",0,0x40800000);
will give you guaranteed 512.00

because it will always make _double as 0x4080000000000000 which is
representation for 512.0000 in 64bit float aka double

but
printf("%f\n",0x40800000);
will give you anything, coz what _double will get will be 0x YYYYYYYY 40800000,
where YYYYYYYY could be any bit pattern picked from neighbouring location, where
0x40800000 is put onto stack during argument passing.

for understanding it further you can try a simple example --
char hello[] = "hello world";
printf("%f,%s\n",0x40800000,hello);

It will never print "hello world" under current code state and is likely to
trash the program execution.

The similar behaviour you can observe under cygwin and linux too. This seems to
be general behaviour with printf code (open source).

Anyone on list please correct me, if i am mistaken, but aren't format specifiers
for float and double different now? %f and %lf (long float).

you can try out (i haven't given it a try but it should work) following quick
modifications to vfnprintf code to see your example (at the beginning of this
mail) working as expected.

make following declaration near _double declaration in same function's code

float _float;

and

#ifdef CYGSEM_LIBC_STDIO_PRINTF_FLOATING_POINT
             case 'f':
                     _float = va_arg(arg, float);
                     _double = (double) _float;
                     goto withrest ;

             case 'e':
             case 'E':
             case 'f':
             case 'g':
             case 'G':
                      _double = va_arg(arg, double);
             withrest :


Mind that, though it is fix in right direction, yet it is likely to break things
where you print things like --

float myfloat=4.0;
printf("%f\n",myfloat);

because compilers normally push enough bytes for a equivalent double (even when
you ask for a float). You can try going through the dump given by
"architecture-specific-objdump -D executable"

hope this detailed explanation solves your doubts.

sandeep



---
Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.507 / Virus Database: 304 - Release Date: 8/4/2003


-- 
Before posting, please read the FAQ: http://sources.redhat.com/fom/ecos
and search the list archive: http://sources.redhat.com/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]