EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Display float/double on LCD

Started by neoalosh November 28, 2005
Hi guys, i'm trying to multiply 53e-7 * 20 and display it on an
interfaced LCD. i'm using ICC12 to compile my program. In Project->
options i set PRINTF version to FLOAT. the line i'm using to produce
the result is:

sprintf(tmpstr1,"%2.8f",period_count*CYCLE_TIME);

where unsigned int period_count = 20;
and float CYCLE_TIME = 53e-7;

I end up getting (-2079.9418945) displayed

when i sprintf(tmpstr1,"%u %2.8f",period_count,CYCLE_TIME);
they are displayed properly...! is there is a compiler option i need to change? Is something wrong
with the sprintf statement?



I think I see the problem, make period_count a float, or typecast it in the
sprintf statement. I think the C compiler is converting the result to
unsigned int, then taking that value and trying to print it as a float.
sprintf(tmpstr1,"%2.8f",(float)period_count*CYCLE_TIME);
_____

From: 68HC12@68HC... [mailto:68HC12@68HC...] On Behalf Of
neoalosh
Sent: Monday, November 28, 2005 12:55 AM
To: 68HC12@68HC...
Subject: [68HC12] Display float/double on LCD
Hi guys, i'm trying to multiply 53e-7 * 20 and display it on an
interfaced LCD. i'm using ICC12 to compile my program. In Project->
options i set PRINTF version to FLOAT. the line i'm using to produce
the result is:

sprintf(tmpstr1,"%2.8f",period_count*CYCLE_TIME);

where unsigned int period_count = 20;
and float CYCLE_TIME = 53e-7;

I end up getting (-2079.9418945) displayed

when i sprintf(tmpstr1,"%u %2.8f",period_count,CYCLE_TIME);
they are displayed properly...! is there is a compiler option i need to change? Is something wrong
with the sprintf statement?
_____

> Terms of Service.
_____


Yes this is how C works. No automatic type promotion is done to match the %
specifier inside the printf like function. As an aside, the type of an
expression is solely dependent on the types of the operands, not the wanted
result. e.g.

int i, j;
float f;

f = i * j;

The multiply will be done as an integer multiply, and not a floating multiply.

At 06:06 AM 11/28/2005, Mark Wyman wrote:

>I think I see the problem, make period_count a float, or typecast it in the
>sprintf statement. I think the C compiler is converting the result to
>unsigned int, then taking that value and trying to print it as a float. >
>sprintf(tmpstr1,"%2.8f",(float)period_count*CYCLE_TIME); >
> _____
>
>From: 68HC12@68HC... [mailto:68HC12@68HC...] On Behalf Of
>neoalosh
>Sent: Monday, November 28, 2005 12:55 AM
>To: 68HC12@68HC...
>Subject: [68HC12] Display float/double on LCD >
>Hi guys, i'm trying to multiply 53e-7 * 20 and display it on an
>interfaced LCD. i'm using ICC12 to compile my program. In Project->
>options i set PRINTF version to FLOAT. the line i'm using to produce
>the result is:
>
>sprintf(tmpstr1,"%2.8f",period_count*CYCLE_TIME);
>
>where unsigned int period_count = 20;
>and float CYCLE_TIME = 53e-7;
>
>I end up getting (-2079.9418945) displayed
>
>when i sprintf(tmpstr1,"%u %2.8f",period_count,CYCLE_TIME);
>they are displayed properly...! >is there is a compiler option i need to change? Is something wrong
>with the sprintf statement? >
> _____
>
>> Terms of Service. >
> _____ >
>Yahoo! Groups Links >
>

// richard (This email is for mailing lists. To reach me directly, please
use richard at imagecraft.com)


> Yes this is how C works. No automatic type promotion is done to match
> the % specifier inside the printf like function. As an aside, the
> type of an expression is solely dependent on the types of the
> operands, not the wanted result. e.g.
>
> int i, j;
> float f;
>
> f = i * j;
>
> The multiply will be done as an integer multiply, and not a floating
> multiply.

The original poster wrote this:

> Hi guys, i'm trying to multiply 53e-7 * 20 and display it on an
> interfaced LCD. i'm using ICC12 to compile my program. In Project->
> options i set PRINTF version to FLOAT. the line i'm using to produce
> the result is:
>
> sprintf(tmpstr1,"%2.8f",period_count*CYCLE_TIME);
>
> where unsigned int period_count = 20;
> and float CYCLE_TIME = 53e-7;

Since CYCLE_TIME is a float, the compiler should convert period_count
to float, do a float multiply and leave the result as a float.
If indeed his code is what he wrote and there are no other problems,
like tempstr1 not being large enough to store the result or
something along these lines, then he hit a compiler bug.

Zoltan


In a message dated 11/28/05 3:29:34 P.M. Eastern Standard Time,
zoltan@zolt... writes:

> sprintf(tmps> sprintf(tmpstr1,"%2.8f",period_count*CYCLE_TIME);
===============================
I think the format specifier needs to be 8.2f, not 2.8f. That'll give 8
places total including dp, and 2 decimal places



Another point is that the sprintf format "%f" expects a double and not a
float.

So I would add an explicit cast to double for such code:

(void)sprintf(tmpstr1,"%2.8f", (double)(period_count*CYCLE_TIME));

There is no sprintf format specifier for float in ANSI-C.

In the past I also saw such strange effects when sprintf was implicitly
defined,
so make sure you include <stdlib.h> before using sprintf.

Daniel

BobGardner@BobG... wrote:

>In a message dated 11/28/05 3:29:34 P.M. Eastern Standard Time,
>zoltan@zolt... writes: >
>> sprintf(tmps> sprintf(tmpstr1,"%2.8f",period_count*CYCLE_TIME);
>>
>>
>===============================
>I think the format specifier needs to be 8.2f, not 2.8f. That'll give 8
>places total including dp, and 2 decimal places >




At 12:22 PM 11/28/2005, Zoltán Kócsi wrote:

> > Yes this is how C works. No automatic type promotion is done to match
> > the % specifier inside the printf like function. As an aside, the
> > type of an expression is solely dependent on the types of the
> > operands, not the wanted result. e.g.
> >
> > int i, j;
> > float f;
> >
> > f = i * j;
> >
> > The multiply will be done as an integer multiply, and not a floating
> > multiply.
>
>The original poster wrote this:
>
> > Hi guys, i'm trying to multiply 53e-7 * 20 and display it on an
> > interfaced LCD. i'm using ICC12 to compile my program. In Project->
> > options i set PRINTF version to FLOAT. the line i'm using to produce
> > the result is:
> >
> > sprintf(tmpstr1,"%2.8f",period_count*CYCLE_TIME);
> >
> > where unsigned int period_count = 20;
> > and float CYCLE_TIME = 53e-7;
>
>Since CYCLE_TIME is a float, the compiler should convert period_count
>to float, do a float multiply and leave the result as a float.
>If indeed his code is what he wrote and there are no other problems,
>like tempstr1 not being large enough to store the result or
>something along these lines, then he hit a compiler bug.

Sorry, I saw his 2nd email whereas he said he typecasts the first operand
and the result is correct so I assumed incorrectly that CYCLE_TIME is an
int. As you say, if there is no other problems with the code, then it would
be a compiler problem is the original multiply is not done in FP form and
the result is not FP. I highly doubt it is a compiler problem though but of
course I could be wrong. Anycase, a simple test program does indicate the
compiler is correct so whatever is happening, is most likely due to other
factors.

>Zoltan >Yahoo! Groups Links >
>

// richard (This email is for mailing lists. To reach me directly, please
use richard at imagecraft.com)


> Another point is that the sprintf format "%f" expects a double and
> not a float.
>
> So I would add an explicit cast to double for such code:
>
> (void)sprintf(tmpstr1,"%2.8f", (double)(period_count*CYCLE_TIME));

You do not have to. The prototype for sprintf() is:
int sprintf( char *, const char *, ... );
Due to the ... it is mandatory for the compiler to perform
the usual type promotions and thus all floats will be automatically
converted to double. That's why you can't even specify a float in the
format string for printf(). It will *never* get a float, even if you
explicitely request it:

double x;
printf( "%f", (float) x );

will first convert x to float, due to your explicite cast and then
convert it back to double, due to the compiler's type promotional
obligation. Since in the first step you lose information, the compiler
can't even optimise it out, it *has* to perform both conversions.

> In the past I also saw such strange effects when sprintf was
> implicitly defined,
> so make sure you include <stdlib.h> before using sprintf.

Well, in this particular case I don't think it is the problem.
The compiler, if it hasn't seen a prototype, should perform the
type promotions, thus turn floats to doubles. Nevertheless, using
?printf(), ?scanf() et al without pulling in stdio.h is indeed
very bad practice.

It is unlikely that it is a compiler error - this is too big a bug to
go unnoticed. It is somewhere else in the code, I think, but since we
haven't seen the code, we can't judge it. However, there is nothing
wrong with the way the sprintf() is written, as far as I can see.

Zoltan




The 2024 Embedded Online Conference