sprintf

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

sprintf

5,299 次查看
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 项奖励
回复
7 回复数

1,498 次查看
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 项奖励
回复

1,498 次查看
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 项奖励
回复

1,498 次查看
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 项奖励
回复

1,498 次查看
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 项奖励
回复

1,498 次查看
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 项奖励
回复

1,498 次查看
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 项奖励
回复

1,498 次查看
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 项奖励
回复