473,382 Members | 1,348 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

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 4873
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Dan Sommers | last post by:
Hi, I have a class whose objects represent physical quantities including uncertainties and units, and I would like more control over the way they print. I have a __str__ method which outputs...
4
by: Roger Leigh | last post by:
Hello, I'm writing a fixed-precision floating point class, based on the ideas in the example fixed_pt class in the "Practical C++ Programming" book by Steve Oualline (O' Reilly). This uses a...
4
by: Tommi Mäkitalo | last post by:
Hi I need to format floating-point-numbers with exact 2 digits after decimal point. I could use printf with "%.2f", but it don't use std::locale. Any ideas? -- Tommi Mäkitalo
5
by: Brandon | last post by:
In a program, I'm using an ostringstream to convert a floating point value to a string. When the numbers are big enough, they are converted using scientific notation. To fix this, I changed the...
4
by: Dave | last post by:
Hi folks, I am trying to develop a routine that will handle sphere-sphere and sphere-triangle collisions and interactions. My aim is to develop a quake style collision engine where a player can...
31
by: JS | last post by:
We have the same floating point intensive C++ program that runs on Windows on Intel chip and on Sun Solaris on SPARC chips. The program reads the exactly the same input files on the two platforms....
2
by: Ingo Nolden | last post by:
Hello, I want to format floats ( doubles ) into small strings of 7 characters. I tried to use std::ostream, but I don't get the desired behaviour. Especially in scientific notation I am not...
5
by: Anton Noll | last post by:
We are using Visual Studio 2003.NET (C++) for the development of our software in the fields digital signal processing and numerical acoustics. One of our programs was working correctly if we are...
687
by: cody | last post by:
no this is no trollposting and please don't get it wrong but iam very curious why people still use C instead of other languages especially C++. i heard people say C++ is slower than C but i can't...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.