Problem with sprintf and float

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem with sprintf and float

4,196 Views
cks
Contributor I
Hi,
I use DEMO9s12xdt512 with CodeWarrior and i have a problem to use sprintf with float.
 
In my project i have included the ainsixbf.lib and stdio.h, here my code :
 
*************************** 
 double toto;
 char chaine[30];
 toto = 1,2345;
 sprintf(chaine,"bonjour");
 
 sprintf(chaine,"%f",toto);
 toto=0.;
**************************
The first sprintf give the right result but when i want to convert "toto", the string don't have the good result.
Any idea ?
Labels (1)
0 Kudos
16 Replies

1,644 Views
CrasyCat
Specialist III
Hello
 
Did you specify you want to use floating point arithmetic while creating your project?
Which is the ANSI library you are linking to the application?
 
CrasyCat
0 Kudos

1,644 Views
cks
Contributor I
It's ok, i resolve the problem : instead of ainsixbf.lib, i use the ainsixb.lib. Now it works. Thanks.
0 Kudos

1,644 Views
J2MEJediMaster
Specialist I
Maybe it's a typo, but let's confirm...

You have a comma instead of a decimal point in your defintion of toto.

If that's not the issue, what value are you getting?

---Tom
0 Kudos

1,644 Views
FWFan
Contributor III
Hi All,
 
I tried to use sprintf() and snprintf(), but the file won't compile.
When I press F1 for help, it says I need a function prototype.
I've include stdio.h but that still didn't help.
Have you guys seen this before?
 
Thank you,
FWFan
0 Kudos

1,644 Views
CrasyCat
Specialist III
Hello
 
Including stdio.h should allow you to use sprintf without any problem.
 
CodeWarrior for HC12 ANSI libraries does not include implementation for snprintf.
So that is probably the reason you get your message.
 
CrasyCat
0 Kudos

1,644 Views
Lundin
Senior Contributor IV
To be picky, ANSI C is an irrelevant standard and the compiler should claim to be ISO C compatible and nothing else. "ANSI C" usually refers to the obsolete American standard from 1989. The current ISO C standard ("C99") does include snprintf().

But as we all know, almost no compiler manufacturers implement that standard, but sticks to the old ISO standard from 1990.
0 Kudos

1,644 Views
FWFan
Contributor III
Hi Lundin,
 
I meant to say "inefficient way".
My apology.
 
FWFan
0 Kudos

1,644 Views
FWFan
Contributor III
Hi CrasyCat,
 
I've tried sprintf() also, but that did not work neither.
I'm using the 8-bit QE128 version of the software.
I've found a way around to display the 7-segment display.
But I like to find an answer for this in case I have to
use it in the future.
 
Thank you for you help.
FWFan
0 Kudos

1,644 Views
CrasyCat
Specialist III
Hello
 
Do you mean you are using the HCS08QE128?
In that case you have posted your question in the wrong forum. This forum is around 16-bit MCU (HCS12, HCS12X).
 
For clarity I would recommend that you create a new post in the 8-bit forum or in the CodeWarrior 8-16 bit forum.
 
Additionally what are you trying to print using sprintf? Floats, int, strings, ....?
 
CrasyCat
0 Kudos

1,644 Views
FWFan
Contributor III
Hi CrasyCat,
 
Yes, I am using that micro.  I was searching in the 8 bit forum but couldn't find the answer.  I thought I would  try it in the general forum.  But somehow ended up in the 16 bit forum.  Sorry about that.   In any case, I was trying to print my float to string so I can extract the digit to display them on the 7 segment display.  Round about way I suppose.  Now I just use typecast to get each digit at a time.  I don't know if that's the professional way to do it or not.  You can see in my attached file.  Perhaps you can give me some hints if you have done something like that before.
 
Thank you for understanding.
FWFan
0 Kudos

1,644 Views
CrasyCat
Specialist III
Hello
 
If you intend to print out floating point variables using sprintf, you need to link with the appropriate ANSI library.
Which ANSI library file are you linking to your application?
 
CrasyCat
0 Kudos

1,644 Views
FWFan
Contributor III
Hi CrasyCat,
 
I wasn't aware of linking ANSI library.
I just included the <stdio.h> in my code.
I'm quite new to firmware so I was not aware
I had to do something like that.
Do you mind giving me a few pointers?
 
Thank you very much.
FWFan
0 Kudos

1,644 Views
Lundin
Senior Contributor IV
Easiest way is to make a new project through the project wizard and select float upon project creation.

You can also change your current project by taking a backup of it, then toss out ansi**.lib and add ansifs.lib instead. You might also want to set the compiler option -Fd to make doubles 32 bit (IEEE32).

--

However, what you should seriously consider is to toss both sprintf() and float numbers out of the project. Using those on an 8-bit MCU is terrible inefficient in every way, and comes with a number of safety hazards as well.

sprintf() should only be regarded as a debugging/hobbyist function. It is mainly there because CW wants to claim ISO C compliance. Not only is the function inefficient, but va_list functions come with a load of undefined/unspecified behavior. Recognized coding standards such as MISRA-C bans the use of stdio.h in all production code.

The float type in C is usually unnecessary in small, real-time systems. You can usually achieve the same things more effectively using solely integers.
0 Kudos

1,644 Views
FWFan
Contributor III
Hi Lundin,
 
Thank you for your reply.
I know it's an efficient way to do what I'm trying to do.
But I've tried and even look up the forum for some hints
but still couldn't find it.
Basically, I'm trying to write the decimal numbers up
to 2 places on my 3 digits 7-segment display.
I'm trying to find a way to use my lookup table
for 0-9.  It is implemented in the updateDisplay() subroutine.
Can you spare some hints?
 
Thank you,
FWFan
0 Kudos

1,644 Views
CompilerGuru
NXP Employee
NXP Employee
First I would suggest not to place the lookup table on the stack.
> char display_digits[10] = {
As it does not change, make it const and static:
> static const char display_digits[10] = {
So it ends up directly in flash and does not have to be created on the stack
which is quite expensive.

Next, I don't see the real need for the float. Currently the code is:

>  byte highVal =...
>  highValDec = (float) highVal * 0.0121;

So instead of computing a float in the 0.0 .. 3.0855 range, I would suggest
to compute an integer in the 0 .. 30855 range and just print a "." inside of the output
>  byte highVal =...
>  unsigned int highValDec =  highVal * 121; // highValDec in 0..30855 range.

Then the computation of the 3 digits need a simple integer division
and a multiplication operation per digit,
a lot cheaper than any floating point operation.

> temp_hi = highValDec / 10000;
> highValDec -= temp_hi * 10000;
> temp_med = highValDec / 1000;
> highValDec -= temp_med * 1000;
> temp_low = highValDec / 100;
> highValDec -= temp_low * 100;

or even:
> highValDec /= 100; // cut off trailing 2 digits.
> temp_hi = highValDec / 100;
> highValDec -= temp_hi * 100;
> temp_med = highValDec / 10;
> highValDec -= temp_med * 10;
> temp_low = highValDec;

Daniel

PS: All code untested, just as idea.



0 Kudos

1,644 Views
FWFan
Contributor III
Hi CompilerGuru,
 
Thank you very much for your help.
I was trying to find something like that but I couldn't figure it out.
I was forced to use typcasting in the end.
But now I can do it a professional way.
 
Also thanks for your tip on the constant declaration.
I'm getting some more experience now.
 
I really appreciate it.
FWFan
0 Kudos