Number of digits of float value

M

Marc Schellens

Is there a standard way of determining the number of digits
a float needs (base 10) to be printed (the integer part)?

log10 is too expensive.
As is a loop dividing by 10.

I could think of something dividing by 10^numeric_limits::max_exponent10/2,
then dividing by
10^numeric_limits::max_exponent10/4,
....

but I don't want to reinvent the wheel as this seems to be
a very basic/often needed function.

thanks,
marc
 
I

Ivan Vecerina

Marc Schellens said:
Is there a standard way of determining the number of digits
a float needs (base 10) to be printed (the integer part)?

log10 is too expensive.
As is a loop dividing by 10.

I could think of something dividing by 10^numeric_limits::max_exponent10/2,
then dividing by
10^numeric_limits::max_exponent10/4,
...

but I don't want to reinvent the wheel as this seems to be
a very basic/often needed function.
Not needed that often if you use e.g. stringstream.

In C, many will simply use sprintf and strlen: first print
it to a temporary buffer, then copy it to a final destination.

Are log10 or a loop really too expensive?

Be careful as long as you are working with a floating point
value, subtle rounding errors could happen in rare cases
and lead to nasty bugs.
If you know the range of values that can occur, and can
convert the float to an integer, and performance really is
critical, you could use something like (for int val in 0..9999):
int numDigits = (val>=100) ? ( val>=1000 ? 4 : 3 )
: ( val>=10 ? 2 : 1 );

hth,
Ivan
 
M

Marc Schellens

Ivan said:
Not needed that often if you use e.g. stringstream.

In C, many will simply use sprintf and strlen: first print
it to a temporary buffer, then copy it to a final destination.

Are log10 or a loop really too expensive?

Its for an interpreter (GDL - gnudatalanguage)
Large arrays are put out this way.
Therefore I think log10 and a loop is to expensive, ie.
as there are faster ways (like in your example) I would like to
implement these.
Be careful as long as you are working with a floating point
value, subtle rounding errors could happen in rare cases
and lead to nasty bugs.
If you know the range of values that can occur, and can
convert the float to an integer, and performance really is
critical, you could use something like (for int val in 0..9999):
int numDigits = (val>=100) ? ( val>=1000 ? 4 : 3 )
: ( val>=10 ? 2 : 1 );

Anyway, I thought there might be a standard way.
Right now I implemented it with ostringstream, but that is still
expensive I guess.

Thanks anyway,
marc
 
K

Karl Heinz Buchegger

Marc said:
Anyway, I thought there might be a standard way.
Right now I implemented it with ostringstream, but that is still
expensive I guess.

I guess you are right.
Thats simply becase the ostringstream still has to do a loop
dividing by 10. But it has to do other things as well. While
your loop only counts how often it has been executed, the
loop in the stream formatting has to format the individual
digits also.

But to be 100% sure, some testing would be needed.
 
I

Ivan Vecerina

Marc Schellens said:
Its for an interpreter (GDL - gnudatalanguage)
Large arrays are put out this way.
Therefore I think log10 and a loop is to expensive, ie.
as there are faster ways (like in your example) I would like to
implement these.
Things can be made faster, especially once you have an integer.
But would this step really be the limiting factor?
Anyway, I thought there might be a standard way.
Right now I implemented it with ostringstream, but that is still
expensive I guess.
Note that on many platforms, C++ streams still are significantly
slower than sprintf. And this will have a much greater impact
than the digit counting.
An integer-to-digits routine is also easy enough to implement,
and can be made faster by going backwards (from the end of the
buffer upwards).

If you provide more context around what you are trying to optimize,
I am sure that we can find more effective ways to improve
performance (than by working on digit counting).


Kind regards,
Ivan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top