sprintf

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

sprintf

5,298 Views
ramabh
Contributor I
Hi Everybody..
 
I am new to this forum...
But i found it very useful as many people are helping each others....
 
I am working on MC9s12dt128 freescale 16 bit controller.
The problem is i am using sprintf function with floating point values.I am not getting output correctly.
I included both lib files(libi,libf.h12)
 
And my linker file is this..
where uyou can check my stack value also...

+seg .eeprom -b0x800 -nEEPROM -m0x7FF -sEEPROM # 2k EEPROM remapped from 0x0 in CRTSI.S
+seg .data -b 0x2000 -m 0x1FFF -n IRAM -s RAM   # 8K RAM for Variable storage
+seg .bss  -aIRAM  -sRAM
+def __sbss=@.bss
+def _INITEE=0x12
+def _ESTAT=0x115
+def _ECMD=0x116
+seg .text -b0xF8000 -o 0x4000 -m 0x4000  -nFIXED1  -sCODE 
+seg .const -aFIXED1           # Same as PPAGE = 0x3E offset 0x8000

+seg .text -b0xFC000 -o 0xC000 -m 0x3F80  -nFIXED2  -sCODE -ck  
+seg .const -aFIXED2  -nCFIXED2  -it                     

+seg .const -b 0xFFF80 -o 0xFF80
#+def __stack=0x2FFE  
+def __stack=0x3FFF   
 
I read many of our forums where people mentioned same kind of problem.
What ever the sugesstions u mentioned i tried but still not working....
and this is my code
u32floatval = 4.323;
 memset(u8Buf,'\0',sizeof(u8Buf));
 sprintf(u8Buf,"%0.3f",u32floatval);
 
in the u8Buf i am getting 2.270 instead of 4.323
 
Any one please guide me
0 Kudos
Reply
7 Replies

1,497 Views
kef
Specialist I
ramabh,
 
4.323 as 64bit double is stored in mem as 8 bytes:
 
  40114ac0 83126e98
 
First 4 bytes of ^^ this, treated as 32bits float, gives 2.2701873779296875
 
Looks like compiler promotes your 32bit u32bitfloatval  to 64bit double and I guess that you linked with library that was compiled with option something like "double is 32bits wide". Either enable the same option when compiling your code or link with printf that supports 64bits double.
 
Regards
Edward
0 Kudos
Reply

1,497 Views
ramabh
Contributor I
Hi
 
I gone through code warrier board but i didnot get the solution as i made the things whatever mentioned in it.
 
and Edward ..
I checked how my flaot value is storing in memory
for 4.323 float value....in memory it is 408a5604 but not as u mentioned 40114ac083126e98
 
I even checked by taking a double value but still  i am getting the same result as 2.27 only
 
 
 
0 Kudos
Reply

1,497 Views
kef
Specialist I
ramabh,
 
You probably checked in memory what's in u32floatval. You should check also what's is pushed to the stack when calling sprintf.
 
You said that in memory you have 408a5604. This is 32 bit float with more exact value of 4.322999954223632812. Now convert it to double and you will get 64 bit double encoded as something like 40114ac080000000. Where upper 32bit part of this corresponds to float with value 2.27018737792969. And this explains what happens:
compiler converts your float to double, pushes it and possible other printf args to stack. sprintf gets called, but sprintf was compiled with double precision off and as a result printf pulls just treats 4.32 double as float and prints 2.27 instead of 4.32.
 
 
0 Kudos
Reply

1,497 Views
ramabh
Contributor I
hi edward....
Thank u for ur help...
I checked the value on the Stack...its exactly what u said...its very intersting at the same time confusing too.........
 
But i didnot understand where to change my compiler settings.........
 
Any ways I will try.....once again thank u
0 Kudos
Reply

1,497 Views
kef
Specialist I
Hi
 
I don't know compiler you are using. From you first message it looks like Cosmic linker file. In other message you were talking about CodeWarrior. I'm not familiar with these. Look into manuals for how to switch between 32bits and 64bits double type.
 
From what I know, in CW you should add into project valid library file. There are several versions of precompiled lib-files. One group of libs is compiled with banked memory enabled, another group is compiled with banked mem off. Also there are another subgroups of libs, ones compiled for floating point off, another ones compiled with double's being 32bits wide and another ones compiled with double's being 64bits wide. And in every case printf code must be different a bit. I can't tell you what exactly you need to do to make it working, I'm not familiar with these tools. Try to find these options in manuals.
 
For now, since you don't know what libs to link and what options to change, you could try this hack:
 
u32floatval = 4.323;
 sprintf(u8Buf,"%0.3f",   *(long*)&u32floatval);
 
*(long*)& is supposed to inhibit promotion from float to double and push u32floatval to the stack unaltered, as 32 bits float. This should work in your case because printf decides what's on stack from looking at format string. But better use right options and right libs.
 
Regards
 
0 Kudos
Reply

1,497 Views
ramabh
Contributor I
Hai...Edward....
 
I am using Cosmic compiler and i came to know what library file i have to include and it is libd
and its working fine now.
 
Initially what i did was i added libf file .  I thought as i am using floating point values i included that floating library.With all ur hints i came to know that i have to include double precision library.
 
Thank u edward..for ur timely and valuable support..
0 Kudos
Reply

1,497 Views
Alban
Senior Contributor II
Hello and Welcome,
 
printf() and sprintf() have been extensively discussed in the CodeWarrior board.
 
Browsing or searching that board will show you how to use these functions.
 
Cheers,
Alban.
0 Kudos
Reply