Sign in

Not a member? | Forgot your Password?

Search Comp.Arch.Embedded

Search tips

Free PDF Downloads

Advanced Linux Programming

What Every Programmer Should Know About Memory

Introduction to Embedded Systems

C++ Tutorial

Embedded Systems - Theory and Design Methodology

Microcontroller Programming and Interfacing

Introduction to Microcontrollers


More Free PDF Downloads

Recent Blogs on EmbeddedRelated

Coding - Step 0: Setting Up a Development Environment
posted by Stephen Friederichs


Book Review: "Turing's Cathedral"
posted by Jason Sachs


Ada - 7 Segments and Catching Errors
posted by Mike Silva


OOKLONE: a cheap RF 433.92MHz OOK frame cloner
posted by Fabien Le Mentec


Practical protection against dust and water (i.e. IP protection)
posted by Dr Cagri Tanriover


Introduction to Microcontrollers

1 - Beginnings

2 - Further Beginnings

3 - Hello World

4 - More On GPIO

5 - Interrupts

6 - More On Interrupts

7 - Timers

8 - Adding Some Real-World Hardware

9 - More Timers and Displays

10 - Buttons and Bouncing

11 - Button Matrix & Auto Repeating

12 - Driving WS2812 RGB LEDs

13 - 7-segment displays & Multiplexing

See Also

ElectronicsDSPFPGA

Discussion Groups | Comp.Arch.Embedded | converting float to ascii w/o printf

There are 36 messages in this thread.

You are currently looking at messages 1 to 10.


So far in November, you have voted 0 times ou of a total of 4 votes by the community.
Please help us clean the archives from unuseful discussion threads by using the voting system! Details here.

converting float to ascii w/o printf - Ron Blancarte - 2007-03-27 16:45:00

Now, i have googled this some, with not much as far as results, so I
though I would ask here to see what kind of luck I would have.

I am using the Analog Devices ADuC831 (8052 ISA) part to do data
acquisition and transmission.  I have some data that is being held as
floating point (single precision IEEE 754 format).  Some of this data
needs to be outputted to serial on request.  This is where my request
comes in.  Currently I am using sprintf() to format this output into
my buffer.  HOWEVER, the footprint of this code is making it less than
desirable to use (over 1100 bytes of code space and nearly 30 bytes of
memory).  So I am looking to do the output on my own.

And to this means, I have succeeded, to an extent.  So far I have
removed my need for sprintf() in printing HEX format, as well as ints
and chars.  My problem is with floats.  I have not yet attempted
standard notation:
			3.1415926
But I did write an exponent formula.
			3.141593E+00
I even got the rounding.  HOWEVER, this is using simple multiplies and
divides, by 10, to achieve it's goals.  And this introduces my
problem.  Since a few of the numbers go out to 6 digits of precision,
I am having problems with these last digits outputting correctly.  For
example:

Value entered:		6.791775E-08
Value displayed:	6.791777E-08
Hex value on chip:	  0x3391DA2E (6.7917753e-8)

Clearly, the entered value is being stored correctly and the displayed
value, while close, is just slightly off.  So is there a way to do
this without this error induced by my multiplications by 10 (and still
not using sprintf()?

RonB


--------------------------------------------------
"It is human nature to take shortcuts in thinking"
--------------------------------------------------

Re: converting float to ascii w/o printf - Anton Erasmus - 2007-03-27 17:19:00

On Tue, 27 Mar 2007 15:45:49 -0500, Ron Blancarte
<r...@---TAKETHISOUT---.blancarte.com> wrote:

>Now, i have googled this some, with not much as far as results, so I
>though I would ask here to see what kind of luck I would have.
>
>I am using the Analog Devices ADuC831 (8052 ISA) part to do data
>acquisition and transmission.  I have some data that is being held as
>floating point (single precision IEEE 754 format).  Some of this data
>needs to be outputted to serial on request.  This is where my request
>comes in.  Currently I am using sprintf() to format this output into
>my buffer.  HOWEVER, the footprint of this code is making it less than
>desirable to use (over 1100 bytes of code space and nearly 30 bytes of
>memory).  So I am looking to do the output on my own.
>
>And to this means, I have succeeded, to an extent.  So far I have
>removed my need for sprintf() in printing HEX format, as well as ints
>and chars.  My problem is with floats.  I have not yet attempted
>standard notation:
>			3.1415926
>But I did write an exponent formula.
>			3.141593E+00
>I even got the rounding.  HOWEVER, this is using simple multiplies and
>divides, by 10, to achieve it's goals.  And this introduces my
>problem.  Since a few of the numbers go out to 6 digits of precision,
>I am having problems with these last digits outputting correctly.  For
>example:
>
>Value entered:		6.791775E-08
>Value displayed:	6.791777E-08
>Hex value on chip:	  0x3391DA2E (6.7917753e-8)
>
>Clearly, the entered value is being stored correctly and the displayed
>value, while close, is just slightly off.  So is there a way to do
>this without this error induced by my multiplications by 10 (and still
>not using sprintf()?
>

Depending on exactly which development environment you are using,
check if you have the ftoa function available. Quite a lot of the
compilers for the 8 bit MCUs include this function.
Do you really need to store the information in floating point format ?
The 8051 is not particularly suitable for handling floating point.
Keeping the data in integer or fixed point format, and only converting
to floating point when necessary should help reduce your code
footprint.

Regards
  Anton Erasmus


Re: converting float to ascii w/o printf - Wilco Dijkstra - 2007-03-27 17:34:00

"Ron Blancarte" <r...@---TAKETHISOUT---.blancarte.com> wrote in message 
news:c...@4ax.com...

> Clearly, the entered value is being stored correctly and the displayed
> value, while close, is just slightly off.  So is there a way to do
> this without this error induced by my multiplications by 10 (and still
> not using sprintf()?

The correct way of doing this is to only do one normalizing multiply
or divide by a power of 10, so you only get one roundoff error. Powers
of 10 are exact in floats up to 10^10, for a wider dynamic range you
get multiple roundoff errors unless you use more precision. After
normalization you use integer arithmetic to extract the digits.

My advice would be to use integer-only arithmetic for normalization,
this way you get less roundoff error over much larger ranges.
Getting this right is non-trivial, that is why floating point printf is so
large. If you don't mind a large roundoff error then you can make
it smaller, but it is extremely hard to make it both small and accurate...

Wilco 



Re: converting float to ascii w/o printf - Thad Smith - 2007-03-27 20:30:00

Wilco Dijkstra wrote:
> "Ron Blancarte" <r...@---TAKETHISOUT---.blancarte.com> wrote in message 
> news:c...@4ax.com...
> 
>>Clearly, the entered value is being stored correctly and the displayed
>>value, while close, is just slightly off.  So is there a way to do
>>this without this error induced by my multiplications by 10 (and still
>>not using sprintf()?
> 
> The correct way of doing this is to only do one normalizing multiply
> or divide by a power of 10, so you only get one roundoff error. Powers
> of 10 are exact in floats up to 10^10, for a wider dynamic range you
> get multiple roundoff errors unless you use more precision. After
> normalization you use integer arithmetic to extract the digits.

Agreed.

> My advice would be to use integer-only arithmetic for normalization,
> this way you get less roundoff error over much larger ranges.

Hmmm, I don't understand the recommendation here.  I would say multiply 
or divide by the proper (exact) power of 10 to get a number in the range 
-9999999..9999999, add a rounding factor (-0.5 or +0.5), convert to a 
32-bit integer, convert that to a 7-digit character string, then format.

-- 
Thad

Re: converting float to ascii w/o printf - Ron Blancarte - 2007-03-27 21:08:00

On Tue, 27 Mar 2007 23:19:29 +0200 (while OU was sucking), Anton
Erasmus wrote:
>On Tue, 27 Mar 2007 15:45:49 -0500, Ron Blancarte
><r...@---TAKETHISOUT---.blancarte.com> wrote:
>
>>Now, i have googled this some, with not much as far as results, so I
>>though I would ask here to see what kind of luck I would have.
>>
>>I am using the Analog Devices ADuC831 (8052 ISA) part to do data
>>acquisition and transmission.  I have some data that is being held as
>>floating point (single precision IEEE 754 format).  Some of this data
>>needs to be outputted to serial on request.  This is where my request
>>comes in.  Currently I am using sprintf() to format this output into
>>my buffer.  HOWEVER, the footprint of this code is making it less than
>>desirable to use (over 1100 bytes of code space and nearly 30 bytes of
>>memory).  So I am looking to do the output on my own.
>>
>>And to this means, I have succeeded, to an extent.  So far I have
>>removed my need for sprintf() in printing HEX format, as well as ints
>>and chars.  My problem is with floats.  I have not yet attempted
>>standard notation:
>>			3.1415926
>>But I did write an exponent formula.
>>			3.141593E+00
>>I even got the rounding.  HOWEVER, this is using simple multiplies and
>>divides, by 10, to achieve it's goals.  And this introduces my
>>problem.  Since a few of the numbers go out to 6 digits of precision,
>>I am having problems with these last digits outputting correctly.  For
>>example:
>>
>>Value entered:		6.791775E-08
>>Value displayed:	6.791777E-08
>>Hex value on chip:	  0x3391DA2E (6.7917753e-8)
>>
>>Clearly, the entered value is being stored correctly and the displayed
>>value, while close, is just slightly off.  So is there a way to do
>>this without this error induced by my multiplications by 10 (and still
>>not using sprintf()?
>>
>
>Depending on exactly which development environment you are using,
>check if you have the ftoa function available. Quite a lot of the
>compilers for the 8 bit MCUs include this function.
>Do you really need to store the information in floating point format ?
>The 8051 is not particularly suitable for handling floating point.
>Keeping the data in integer or fixed point format, and only converting
>to floating point when necessary should help reduce your code
>footprint.

Well I hvae to pick my poison.  Since this is for a measurement
application, that does involve trig, I will take my chances with FP in
this case.  Besides, that portion of my code is not the problem.
Around half of my code (in size) is a command handler, of which this
output is part of.  I have been able to take chunks out of it slowly,
cutting nearly 8k out of it, with some optimization and pulling out
standard functions (like replacing strcmp with my own version).

And unfortunatly Keil doesn't appear to have the ftoa() funciton
included w/ it.  So that is out.

RonB


--------------------------------------------------
"It is human nature to take shortcuts in thinking"
--------------------------------------------------

Re: converting float to ascii w/o printf - Paul Keinanen - 2007-03-28 01:10:00

On Tue, 27 Mar 2007 15:45:49 -0500, Ron Blancarte
<r...@---TAKETHISOUT---.blancarte.com> wrote:

>I am using the Analog Devices ADuC831 (8052 ISA) part to do data
>acquisition and transmission.  I have some data that is being held as
>floating point (single precision IEEE 754 format).  Some of this data
>needs to be outputted to serial on request.  

Is this serial port connected to a bigger system, such as a PC ? 

Could you run your own receiver program on this system ?

If this is the case and you don't want to send binary data directly
over the UART, simply split the 32 bit float into eight 4 bit fields,
convert each field to hex and send over the serial line. At the
receiver end of the line, do the opposite conversion. Since the
receiving system would most likely also use IEEE 754 floats, no extra
conversion on the receiver end is needed and the value can be
displayed using printf on the receiving device.

Paul
 

Re: converting float to ascii w/o printf - John Speth - 2007-03-28 10:31:00

> And unfortunatly Keil doesn't appear to have the ftoa() funciton
> included w/ it.  So that is out.

A moderate amount of digging on the web will get you loads of C source code 
for just about all those classic runtime C lib functions that you're 
missing.  That stuff has been in the public domain for years.

There are efficient and not so efficient versions of sprintf() and ftoa() to 
be found so you'll want to evaluate several to find the one that suits your 
needs.  The bonus is that you're getting source code so you can customize to 
your heart's content.

JJS



Re: converting float to ascii w/o printf - Wilco Dijkstra - 2007-03-28 10:38:00

"Thad Smith" <T...@acm.org> wrote in message 
news:4609b2ec$0$47168$8...@auth.newsreader.octanews.com...
> Wilco Dijkstra wrote:
>> "Ron Blancarte" <r...@---TAKETHISOUT---.blancarte.com> wrote in message 
>> news:c...@4ax.com...
>>
>>>Clearly, the entered value is being stored correctly and the displayed
>>>value, while close, is just slightly off.  So is there a way to do
>>>this without this error induced by my multiplications by 10 (and still
>>>not using sprintf()?
>>
>> The correct way of doing this is to only do one normalizing multiply
>> or divide by a power of 10, so you only get one roundoff error. Powers
>> of 10 are exact in floats up to 10^10, for a wider dynamic range you
>> get multiple roundoff errors unless you use more precision. After
>> normalization you use integer arithmetic to extract the digits.
>
> Agreed.
>
>> My advice would be to use integer-only arithmetic for normalization,
>> this way you get less roundoff error over much larger ranges.
>
> Hmmm, I don't understand the recommendation here.  I would say multiply or divide by the 
> proper (exact) power of 10 to get a number in the range -9999999..9999999, add a 
> rounding factor (-0.5 or +0.5), convert to a 32-bit integer, convert that to a 7-digit 
> character string, then format.

What I mean is that if you do the normalization multiply/divide using
integer arithmetic, you get more precision, eg. 32 bits rathern than 24
when using float. This gives you larger powers of 10 that can be
represented exactly and a more accurate result after normalization
(and more control over rounding). Integer arithmetic makes even more
sense if you use emulated floating point.

Wilco




Re: converting float to ascii w/o printf - Bill Davy - 2007-03-28 11:42:00

fcvt and ecvt might also bear thinking about.

"John Speth" <j...@yahoo.com> wrote in message 
news:eudu8n$s8b$1...@aioe.org...
>> And unfortunatly Keil doesn't appear to have the ftoa() funciton
>> included w/ it.  So that is out.
>
> A moderate amount of digging on the web will get you loads of C source 
> code for just about all those classic runtime C lib functions that you're 
> missing.  That stuff has been in the public domain for years.
>
> There are efficient and not so efficient versions of sprintf() and ftoa() 
> to be found so you'll want to evaluate several to find the one that suits 
> your needs.  The bonus is that you're getting source code so you can 
> customize to your heart's content.
>
> JJS
>
> 



Re: converting float to ascii w/o printf - Everett M. Greene - 2007-03-28 14:22:00

"Wilco Dijkstra" <W...@ntlworld.com> writes:
> "Thad Smith" <T...@acm.org> wrote in message 
> > Wilco Dijkstra wrote:
> >> "Ron Blancarte" <r...@---TAKETHISOUT---.blancarte.com> wrote in message 
> >>
> >>>Clearly, the entered value is being stored correctly and the displayed
> >>>value, while close, is just slightly off.  So is there a way to do
> >>>this without this error induced by my multiplications by 10 (and still
> >>>not using sprintf()?
> >>
> >> The correct way of doing this is to only do one normalizing multiply
> >> or divide by a power of 10, so you only get one roundoff error. Powers
> >> of 10 are exact in floats up to 10^10, for a wider dynamic range you
> >> get multiple roundoff errors unless you use more precision. After
> >> normalization you use integer arithmetic to extract the digits.
> >
> > Agreed.
> >
> >> My advice would be to use integer-only arithmetic for normalization,
> >> this way you get less roundoff error over much larger ranges.
> >
> > Hmmm, I don't understand the recommendation here.  I would say multiply or divide by the 
> > proper (exact) power of 10 to get a number in the range -9999999..9999999, add a 
> > rounding factor (-0.5 or +0.5), convert to a 32-bit integer, convert that to a 7-digit 
> > character string, then format.
> 
> What I mean is that if you do the normalization multiply/divide using
> integer arithmetic, you get more precision, eg. 32 bits rathern than 24
> when using float. This gives you larger powers of 10 that can be
> represented exactly and a more accurate result after normalization
> (and more control over rounding). Integer arithmetic makes even more
> sense if you use emulated floating point.

And don't forget to look at the accuracy of the data
before getting wound around the axle of precision.
If the source of the data is an 8-bit ADC, for
instance, no amount of fancy footwork is going to
get you three decimal place accuracy.  If the
problem is ill-conditioned, not much of anything
will help.

| 1 | | 3 | 4 |