# Printing significant digits of a floating point number

Discussion in 'C++' started by Christoph Bartoschek, Apr 18, 2009.

1. ### Christoph BartoschekGuest

Hi,

I would like to print floating point numbers such that non-scientific output
is used and all significant digits are printed:

template <typename T> void print_number(T num) {
std::cout << ...
}

Here are examples of what I would expect if the floating point type has 6
significant digits:

float a = 0.5;
print_number(a) gives 0.5
// Trailing zeros are not printed

float b = 0.000000000012345678;
print_number(b) gives 0.0000000000123456
// Because non-scientific output is used the output is quite large

float c = 1234567.89;
print_number(c) gives 1234560
// Only the significant digits are printed. A trailing .0 would also be ok.

Is there a way to achieve the desired result by a simple function? I do not
want to reimplement the printf functionality.

Thanks,
Christoph

Christoph Bartoschek, Apr 18, 2009

2. ### Michael SchultzGuest

"Christoph Bartoschek" <> wrote in message
news:...
> Hi,
>
> I would like to print floating point numbers such that non-scientific
> output
> is used and all significant digits are printed:
>
> template <typename T> void print_number(T num) {
> std::cout << ...
> }
>
> Here are examples of what I would expect if the floating point type has 6
> significant digits:
>
> float a = 0.5;
> print_number(a) gives 0.5
> // Trailing zeros are not printed
>
> float b = 0.000000000012345678;
> print_number(b) gives 0.0000000000123456
> // Because non-scientific output is used the output is quite large
>
> float c = 1234567.89;
> print_number(c) gives 1234560
> // Only the significant digits are printed. A trailing .0 would also be
> ok.
>
> Is there a way to achieve the desired result by a simple function? I do
> not
> want to reimplement the printf functionality.
>
> Thanks,
> Christoph

Have you tried using std::setprecision(int num_of_places)? (found in
#include <iomanip)

Michael Schultz, Apr 18, 2009

3. ### Christoph BartoschekGuest

Michael Schultz wrote:
>
> Have you tried using std::setprecision(int num_of_places)? (found in
> #include <iomanip)

Yes. But together with std::fixed this prints too many trailing zeros.

Christoph

Christoph Bartoschek, Apr 18, 2009
4. ### Christoph BartoschekGuest

Obnoxious User wrote:

> On Sat, 18 Apr 2009 22:15:05 +0200, Christoph Bartoschek wrote:
>
>> Michael Schultz wrote:
>>>
>>> Have you tried using std::setprecision(int num_of_places)? (found in
>>> #include <iomanip)

>>
>> Yes. But together with std::fixed this prints too many trailing zeros.
>>

>
> Remove the zeros then.
>

But for the second case not enough digits are printed if I use 6 as the
precision of float:

0.000000

Christoph

Christoph Bartoschek, Apr 18, 2009
5. ### James KanzeGuest

On Apr 18, 9:14 pm, Christoph Bartoschek <> wrote:

> I would like to print floating point numbers such that
> non-scientific output is used and all significant digits are
> printed:

> template <typename T> void print_number(T num) {
> std::cout << ...
> }

> Here are examples of what I would expect if the floating point
> type has 6 significant digits:

> float a = 0.5;
> print_number(a) gives 0.5
> // Trailing zeros are not printed

> float b = 0.000000000012345678;
> print_number(b) gives 0.0000000000123456
> // Because non-scientific output is used the output is quite large

> float c = 1234567.89;
> print_number(c) gives 1234560
> // Only the significant digits are printed. A trailing .0 would also be ok.

> Is there a way to achieve the desired result by a simple
> function?

A priori, no. You want to specify precision, but used fixed
format. In fixed format, however, the presicion argument
specifies the number of digits after the decimal, not the
precision.

There are two possible solutions: either you format using
scientific format, then extract the characters to create the
format you want, or you determine the magnitude of the value,
and set the precision accordingly.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

James Kanze, Apr 19, 2009
6. ### Christoph BartoschekGuest

> A priori, no. You want to specify precision, but used fixed
> format. In fixed format, however, the presicion argument
> specifies the number of digits after the decimal, not the
> precision.

It sounds like bad design. The same setting has two different meanings.

I see that there is no way to get the result in a single computation without
rewriting printf.

Thanks,
Christoph

Christoph Bartoschek, Apr 20, 2009
7. ### James KanzeGuest

On Apr 20, 7:01 pm, Christoph Bartoschek <> wrote:
> > A priori, no. You want to specify precision, but used fixed
> > format. In fixed format, however, the presicion argument
> > specifies the number of digits after the decimal, not the
> > precision.

> It sounds like bad design. The same setting has two different
> meanings.

History. In C++, the precision field is designed to have the
same meaning as the number following the . in a printf format
specifier. And in printf (in C), the format specifiers are more
or less based on Fortran, at least for %f and %e.

It also corresponds to what most people need, most of the time.
If you're using fixed format, you normally want the be able to
line up the decimal points in a table. And that means that you
want to specify the number of digits after the decimal, and not
the actual precision. With scientific format, of course, the
precision is always one more digit than the number of digits
after the decimal, so it doesn't matter. And in the default
format, the library chooses the format, based on the actual
value and the requested precision---in that case, you really do
have to specify the precision. So pragmatically, it's probably
the best choice, over all, even if it sounds a little irregular,
as stated above. (The error might be in the name "precision"
for a field whose semantic does depend on the actual formatting
being done. But I'm not sure what else you could call it. And
traditionally, precision has been used for this in fixed format,
even if it isn't strictly correct.)

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

James Kanze, Apr 21, 2009