This is the mail archive of the
ecos-discuss@sources.redhat.com
mailing list for the eCos project.
Re: Question for displaying floating point in eCOSaplication.
- From: "sandeep" <sandeep at codito dot com>
- To: "QiangHuang" <jameshq at liverpool dot ac dot uk>
- Cc: <ecos-discuss at sources dot redhat dot com>
- Date: Fri, 8 Aug 2003 14:11:29 +0530
- Subject: Re: [ECOS] Question for displaying floating point in eCOSaplication.
- References: <ONEOIJPPOKNBBKJKCGLCAEEOCCAA.jameshq@liv.ac.uk>
> 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