468,491 Members | 2,041 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,491 developers. It's quick & easy.

Formatting floating point values in ostream objects

This C program:

#include <stdio.h>
#include <math.h>

int main()
{
float value;
for(value = -1.0f; 1.1f value; value += 0.1f){
printf("%.1f\n", value);
}

return 0;
}

Produces this output:

-1.0
-0.9
-0.8
-0.7
-0.6
-0.5
-0.4
-0.3
-0.2
-0.1
0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0

Trying to write an equivalent C++ program using ostream has proven
tricky. Here is a solution I came up with:

#include <iostream>
#include <cmath>

int main()
{
static const float TOLERANCE = 0.0001f;

using std::cout;
cout << std::showpoint;

for(float value = -1.0f; 1.1f value; value += 0.1f){
cout.precision(1);

float integral = ::floor(value);
if(TOLERANCE ::fabsf(value - integral)){
value = integral;
cout.precision(2);
}

cout << value << '\n';
}

return 0;
}

It seems like a lot more work to accomplish the same thing. I wonder
if there is a better approach
What is the best way to produce this kind of output using an ostream
object?
Jan 19 '08 #1
9 4632
On Jan 19, 3:26 am, tron.tho...@verizon.net wrote:
This C program:
#include <stdio.h>
#include <math.h>
int main()
{
float value;
for(value = -1.0f; 1.1f value; value += 0.1f){
printf("%.1f\n", value);
}
return 0;
}
Produces this output:
-1.0
-0.9
-0.8
-0.7
-0.6
-0.5
-0.4
-0.3
-0.2
-0.1
0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0
Trying to write an equivalent C++ program using ostream has proven
tricky.
What's wrong with:

#include <iostream>

int
main()
{
std::cout.precision( 1 ) ;
std::cout.setf( std::ios::fixed, std::ios::floatfield ) ;
for ( float value = -1.0f ; 1.1f value ; value += 0.1f ) {
std::cout << value << '\n' ;
}
std::cout.flush() ;
return 0 ;
}

? It should have exactly the same semantics as your C program.

(Of course, in a real application, you'd doubtlessly be using a
user defined manipulator, depending on the semantics of the
float. Logical mark-up, not physical.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Jan 19 '08 #2
Alf P. Steinbach wrote:
> static const float TOLERANCE = 0.0001f;

Don't use all uppercase identifiers except for macros.
Isn't that a question of style?

And IMO, if it's a constant then using all uppercase is sensible. It
doesn't matter if it's a preprocessor constant or a const variable.
Jan 19 '08 #3
Alf P. Steinbach wrote:
Also you're incorrectly
indicating that it's a macro, and you're embedding type information in
the name so that (same problem as with Hungarian evilness) a change of
the constness then requires a change of name, or leaves the name
indicating something that's now false.
And if you use your suggested scheme, if you ever change a #define
into a const variable, you'll have to change the name.
Jan 19 '08 #4
Juha Nieminen wrote:
Alf P. Steinbach wrote:
>Also you're incorrectly
indicating that it's a macro, and you're embedding type
information in the name so that (same problem as with Hungarian
evilness) a change of the constness then requires a change of
name, or leaves the name indicating something that's now false.

And if you use your suggested scheme, if you ever change a #define
into a const variable, you'll have to change the name.
Yes, so don't use #defines! :-)
Bo Persson
Jan 19 '08 #5
On Jan 19, 7:01 pm, Juha Nieminen <nos...@thanks.invalidwrote:
Alf P. Steinbach wrote:
Also you're incorrectly indicating that it's a macro, and
you're embedding type information in the name so that (same
problem as with Hungarian evilness) a change of the
constness then requires a change of name, or leaves the name
indicating something that's now false.
And if you use your suggested scheme, if you ever change a #define
into a const variable, you'll have to change the name.
Certainly. You've significantly changed the semantics, so you
have to look at all uses of it again, to be sure that they are
still OK. Changing the name ensures that you do. (Generally
speaking, of course, if it is a constant, it should never be a
macro to begin with. Macros should be reserved for things that
can't be done otherwise.)

That's also an argument against using all caps for const: one
man's constant is another man's variable, and in practice,
constants do have a tendency of becoming variables, e.g. read
from a configuration file. Long before it became a widely
recognized and generally accepted rule, I'd dropped all caps
from constants because of this---I also don't use all caps for
constants in Java, for the same reason.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Jan 20 '08 #6
Bo Persson wrote:
Yes, so don't use #defines! :-)
But in that case all uppercase names become free to use, so you could
as well use them for names of constants... ;)
Jan 20 '08 #7
On Jan 19, 4:04*am, James Kanze <james.ka...@gmail.comwrote:
What's wrong with:

* * #include <iostream>

* * int
* * main()
* * {
* * * * std::cout.precision( 1 ) ;
* * * * std::cout.setf( std::ios::fixed, std::ios::floatfield ) ;
* * * * for ( float value = -1.0f ; 1.1f value ; value += 0.1f ) {
* * * * * * std::cout << value << '\n' ;
* * * * }
* * * * std::cout.flush() ;
* * * * return 0 ;
* * }

? *It should have exactly the same semantics as your C program.

(Of course, in a real application, you'd doubtlessly be using a
user defined manipulator, depending on the semantics of the
float. *Logical mark-up, not physical.)

--
James Kanze (GABI Software) * * * * * * email:james.ka...@gmail.com
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
Thanks James. That is exactly what I was looking for. I think as long
as I define my precision correctly this code with the result I want
for the actual problem I'm trying to solve.

Jan 20 '08 #8
On 2008-01-20 15:46, Juha Nieminen wrote:
Bo Persson wrote:
>Yes, so don't use #defines! :-)

But in that case all uppercase names become free to use, so you could
as well use them for names of constants... ;)
But someone who do not know that you do not use defines might think that
they are defines. There are a lot of things that could be better, but
due to historical reasons we have to live with. All uppercase names are
for historical reasons reserved for defines. You can of course do as you
want but you should be aware of the "dangers".

--
Erik Wikström
Jan 20 '08 #9
On Jan 20, 7:00 pm, "Alf P. Steinbach" <al...@start.nowrote:
* tron.tho...@verizon.net:
On Jan 19, 4:04 am, James Kanze <james.ka...@gmail.comwrote:
What's wrong with:
#include <iostream>
int
main()
{
std::cout.precision( 1 ) ;
std::cout.setf( std::ios::fixed, std::ios::floatfield ) ;
for ( float value = -1.0f ; 1.1f value ; value += 0.1f ) {
std::cout << value << '\n' ;
}
std::cout.flush() ;
return 0 ;
}
? It should have exactly the same semantics as your C program.
(Of course, in a real application, you'd doubtlessly be using a
user defined manipulator, depending on the semantics of the
float. Logical mark-up, not physical.)
Thanks James. That is exactly what I was looking for. I think as long
as I define my precision correctly this code with the result I want
for the actual problem I'm trying to solve.
Note that James very very carefully wrote "same semantics".
That does not mean that the code above has a well-defined result.
Quite. I only addressed the formatting issue, not the more
general problem of floating point arithmetic. This sort of loop
in floating point is just asking for trouble.

--
James Kanze (GABI Software) email:ja*********@gmail.com
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
Jan 20 '08 #10

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Roger Leigh | last post: by
4 posts views Thread by Tommi Mäkitalo | last post: by
5 posts views Thread by Brandon | last post: by
2 posts views Thread by Ingo Nolden | last post: by
5 posts views Thread by Anton Noll | last post: by
687 posts views Thread by cody | last post: by
reply views Thread by NPC403 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.