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
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!
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...
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.
--- 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?
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!