Reply by "sub...@aeolusdevelopment.com" April 11, 20082008-04-11
Robert Adsett wrote
>See frexp (part of the C standard library).
>
>for a preliminary (very short) introduction to them see
>http://www.dinkumware.com/manuals/default.aspx?manual=compleat&page=math.ht
ml
>
>The problem is that will give you a binary fraction and exponent. log is
>probably closer to what you want.

Well log10 but hopefully that was obvious.

Robert

--------------------------------
myhosting.com - Premium Microsoft Windows and Linux web and application
hosting - http://link.myhosting.com/myhosting

An Engineer's Guide to the LPC2100 Series

Reply by Jan Vanek April 10, 20082008-04-10
Hallo Gaspar,

the problem of converting float to string is completelly LPC2000 unrelated, but it is small and interesting, so I tried to implement it. It only works for positive numbers, you'll have to handle negative case yourself. The algorithm works as follows. Assuming you want to print p decimal positions (say p = 2, then print x.yz), I want the to be printed value v, to be v >= 10^p and v < 10^(p+1). So the algorithm multiplies or divides the value with 10 until the condition holds. So if the value was 0.0234 and the precision is 3, after 5 steps of multiplication with 10, the value is 2340. The value is then converted to int and printed with itoa() function. Then the '.' is inserted after first digit. So we have 2.340. The exponent is calculated during the cycle. In the example, it is -2, which is 3 - 5.

void f2s(float value, unsigned int precision, char* buffer)
{
// TODO: handle negative case
if (value < 0)
value = -value;
// limit is 10^precision
unsigned int limit = 1;
for (unsigned int i = precision; i > 0; --i)
limit *= 10;
// wanted value >= limit, value < 10*limit
int exponent = (int)precision;
if (value >= limit)
{
limit *= 10;
while (value >= limit)
{
value /= 10;
++exponent;
}
}
else
{
while (value < limit)
{
value *= 10;
--exponent;
}
}
// print value as int, insert ..
itoa((int)value, buffer+1, 10);
buffer[0] = buffer[1];
buffer[1] = '.';
// add exponent
buffer[precision+2] = 'E';
if (exponent >= 0)
buffer[precision+3] = '+';
else
{
buffer[precision+3] = '-';
exponent = -exponent;
}
itoa(exponent, buffer+precision+4, 10);
}

It was compiled with C++ compiler, so you'll need to move the variable declarations. Hope this helps... I am a embedded-newbie, and I might need some LPC288x help in the future :-)

Jan

----- Original Message -----
From: Gaspar Pollano
To: l...
Sent: Thursday, April 10, 2008 7:18 PM
Subject: [lpc2000] Converting float (or double) number to string in GCC

Hi Forum!

Im working on a project which use float numbers in a LPC2148, using
YAGARTO (GCC,Eclipse,etc,etc).
I need print out floats numbers in a GLCD, using several formats
(like ###0.0 or ###0.00 or 0.00000E00, etc).
My project has a sprintf function wich is a reduced (uC oriented)
version of the GCC's sdtio.h function, without float number support.

How you deal with floats into strings on GCC? (Keil and others
already has "uC-optimized" implementations...)

I think there are few options:
a) Write my own float_to_string function (mhhh :-P)
b) Use gcc sdtlib sprintf (too large for uC??)
c) Use something like "dtoa" (found it on stdlib, but i dont
know how it works!)
d) Other?? (someone have implemented something similiar??)

In addition, my project already has "uC-Optimized" versions of
strtoint, inttostr, strlen, strcpy, strncpy, and similars from ALDS
(ARM LPC Driver Set, of Bastiaan van Kesteren) wich will "collide"
with stdlib from GCC, if included.

Any suggestion will be apreciated,
Thanks in advance!

Gaspar

#ygrp-mkp { BORDER-RIGHT: #d8d8d8 1px solid; PADDING-RIGHT: 14px; BORDER-TOP: #d8d8d8 1px solid; PADDING-LEFT: 14px; PADDING-BOTTOM: 0px; MARGIN: 14px 0px; BORDER-LEFT: #d8d8d8 1px solid; PADDING-TOP: 0px; BORDER-BOTTOM: #d8d8d8 1px solid; FONT-FAMILY: Arial}#ygrp-mkp HR { BORDER-RIGHT: #d8d8d8 1px solid; BORDER-TOP: #d8d8d8 1px solid; BORDER-LEFT: #d8d8d8 1px solid; BORDER-BOTTOM: #d8d8d8 1px solid}#ygrp-mkp #hd { FONT-WEIGHT: bold; FONT-SIZE: 85%; MARGIN: 10px 0px; COLOR: #628c2a; LINE-HEIGHT: 122%}#ygrp-mkp #ads { MARGIN-BOTTOM: 10px}#ygrp-mkp .ad { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px}#ygrp-mkp .ad A { COLOR: #0000ff; TEXT-DECORATION: none}
__________________________________________________


Reply by "sub...@aeolusdevelopment.com" April 10, 20082008-04-10
Gaspar Pollano Wrote
> wrote:
>> How do you code reduce something like strlen (and still have strlen)?
>> There isn't much of a time/space tradeoff to be made.
>
>Of Course :-), the only reason I use this "out-of-library" functions
>is to keep the project simple (not including standards libs, for
>now...)

OK, that's reason (although I'd disagree about it being simpler) but t'aint
code reduced.

>About reducing the number: I need print something
>like "3.26471541E-08" on the GLCD. (for case 1)
>
>Maybe Im unable to understand you, but when you say "reduce" i think
>you mean "getting the first significant digit"?? Is that correct?

Yes, break it up into two numbers
0.326471541 and -9

Print the first as 3.26471541 (after converting to an integer of the
appropriate length) and the second as e-8
>Im thinking in reading the EXPonent (on excess 127) of the 32bit
>float IEEE number and using it to express the exponent on GLCD, then
>read the "mantisa" (Im from Argentina, sorry for mi bad english) and
>print it on the GLCD, an so on.
>Seems to be something common that could be already done for someone
>else...

See frexp (part of the C standard library).

for a preliminary (very short) introduction to them see
http://www.dinkumware.com/manuals/default.aspx?manual=compleat&page=math.htm
l

The problem is that will give you a binary fraction and exponent. log is
probably closer to what you want.

As for your english. It's quite good. Good enough for me to have replied
with informal language (read t'aint above as is not).

Robert

--------------------------------
mail2web - Check your email from the web at
http://link.mail2web.com/mail2web

Reply by Gaspar Pollano April 10, 20082008-04-10
Thanks Robert,

wrote:
> How do you code reduce something like strlen (and still have
strlen)?
> There isn't much of a time/space tradeoff to be made.

Of Course :-), the only reason I use this "out-of-library" functions
is to keep the project simple (not including standards libs, for
now...)

About reducing the number: I need print something
like "3.26471541E-08" on the GLCD. (for case 1)

Maybe Im unable to understand you, but when you say "reduce" i think
you mean "getting the first significant digit"?? Is that correct?

Im thinking in reading the EXPonent (on excess 127) of the 32bit
float IEEE number and using it to express the exponent on GLCD, then
read the "mantisa" (Im from Argentina, sorry for mi bad english) and
print it on the GLCD, an so on.
Seems to be something common that could be already done for someone
else...

Best Regards,
Gaspar

Reply by "sub...@aeolusdevelopment.com" April 10, 20082008-04-10
Gaspar Pollano Wrote
>--- In l..., "subscriptions@..."
> wrote:
>>
>Of course strtoint, inttostr are not standard. They are (like strlen,
>strcpy, strncpy, and similars from ALDS) "code-reduced" and stored in
>a "local" std.c file to avoid including stdlib.h from GCC.

How do you code reduce something like strlen (and still have strlen)?
There isn't much of a time/space tradeoff to be made.

>If I need the stdlib.h, i will rename this "not-standard" functions.
>
>My application need two difents dynamic ranges,
>
>1) represent numbers from -1.0000000E-15 to 1.0000000E+8 (coefs of a
>sixth order polynomical function)

Generic approach
- Reduce number to range between -1 to 1 (keep exponent of course).
Print this (see section 2) and append the exponent. Assuming scientific
notation is OK.
- Reduction left as an exercise for the reader :)

>2) represent numbers from 0 to 10,000.00
>
>Maybe on case 2) there is no need to float to string conversion, just
>multipy and inserting "." on the array, but the case 1) is more
>complex.

Yes, just change to problem to one of printing an integer with an extra
character in it.

Robert

--------------------------------
mail2web.com Enhanced email for the mobile individual based on Microsoft
Exchange - http://link.mail2web.com/Personal/EnhancedEmail

Reply by Gaspar Pollano April 10, 20082008-04-10
--- In l..., "subscriptions@..."
wrote:
>
> Gaspar Pollano Wrote
> >In addition, my project already has "uC-Optimized" versions of
> >strtoint, inttostr,
>
> Well those are non-standard
>
> >strlen, strcpy, strncpy, and similars from ALDS
>
> And I can't imagine how any of these would nee or benefit from
> microcontroller specific optimizations.
> What sort of dynamic range do you need?
>
> Robert
>

Robert,
Of course strtoint, inttostr are not standard. They are (like strlen,
strcpy, strncpy, and similars from ALDS) "code-reduced" and stored in
a "local" std.c file to avoid including stdlib.h from GCC.

If I need the stdlib.h, i will rename this "not-standard" functions.

My application need two difents dynamic ranges,

1) represent numbers from -1.0000000E-15 to 1.0000000E+8 (coefs of a
sixth order polynomical function)
2) represent numbers from 0 to 10,000.00

Maybe on case 2) there is no need to float to string conversion, just
multipy and inserting "." on the array, but the case 1) is more
complex.

Thanks,
Gaspar

Reply by "sub...@aeolusdevelopment.com" April 10, 20082008-04-10
Gaspar Pollano Wrote
>In addition, my project already has "uC-Optimized" versions of
>strtoint, inttostr,

Well those are non-standard

>strlen, strcpy, strncpy, and similars from ALDS

And I can't imagine how any of these would nee or benefit from
microcontroller specific optimizations.
What sort of dynamic range do you need?

Robert

--------------------------------
mail2web.com - Microsoft Exchange solutions from a leading provider -
http://link.mail2web.com/Business/Exchange

Reply by Gaspar Pollano April 10, 20082008-04-10
Hi Forum!

Im working on a project which use float numbers in a LPC2148, using
YAGARTO (GCC,Eclipse,etc,etc).
I need print out floats numbers in a GLCD, using several formats
(like ###0.0 or ###0.00 or 0.00000E00, etc).
My project has a sprintf function wich is a reduced (uC oriented)
version of the GCC's sdtio.h function, without float number support.

How you deal with floats into strings on GCC? (Keil and others
already has "uC-optimized" implementations...)

I think there are few options:
a) Write my own float_to_string function (mhhh :-P)
b) Use gcc sdtlib sprintf (too large for uC??)
c) Use something like "dtoa" (found it on stdlib, but i dont
know how it works!)
d) Other?? (someone have implemented something similiar??)

In addition, my project already has "uC-Optimized" versions of
strtoint, inttostr, strlen, strcpy, strncpy, and similars from ALDS
(ARM LPC Driver Set, of Bastiaan van Kesteren) wich will "collide"
with stdlib from GCC, if included.

Any suggestion will be apreciated,
Thanks in advance!

Gaspar