473,324 Members | 2,239 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,324 software developers and data experts.

Exponential output with cout - should be changed....???

Hi,

I have a program that reads in a couple of numbers from files and then
stores them with some latex-code but I'm not satisfied with the
exponential output, as it takes up too many character spaces. Example:

4.9e+009 - takes 8 characters space (it's a double value). It should
just become 4.9e9 (takes 5 character spaces) since all my numbers are
e-positive (no such thing as e-[something]) and all my numbers are
within 0 <= x <= 9e9. I have no idea about how to do this, but can I use
ostringstream for that?

I assume I must write the exponential number to some string or stream
and then a for loop (pseudo-code):
for( i=0; i<string.length; i++)
{
if(string[i] == 'e')
{
/* damn... What do I do? Remove 3 characters:
the "+" and 2 zeros */
}
}

outfile << exponential_number;
But there's probably a much better and efficient method.
BTW: Something went wrong, as I tried to make a minimal example for
you... I must have overseen something:

-----------
#include <iostream>
#include <iomanip /* for std::setfill(), std::setw() */

using namespace std;

int main()
{
double d1 = 8.126e9;

setw(5);
cout << "d1 = " << setprecision(1) << ios::scientific << d1 << endl;
return 0;
}

-----------

The above program prints:

d1 = 2568e+09

???? Where did that number come from?

As said: My real program uses outfile:

outfile << " & " << setw(15) << twoDimens[i][j];

So once I know how how strip 3 characters from the output (after the
'e') I can implement it... Any suggestions?
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Nov 5 '06 #1
8 3227
Martin Jørgensen <ho**********@hotmail.comwrote:
>4.9e+009 - takes 8 characters space (it's a double value). It should
just become 4.9e9 (takes 5 character spaces) since all my numbers are
e-positive (no such thing as e-[something]) and all my numbers are
within 0 <= x <= 9e9. I have no idea about how to do this, but can I use
ostringstream for that?
I like printf() and its conversion specifications; %3.2e gives
a pretty compact output.

But not sure how to get rid of that + , other than by postfiltering.

Steve
Nov 5 '06 #2

Martin Jørgensen wrote in message
<45*********************@dread12.news.tele.dk>.. .
>Hi,

BTW: Something went wrong, as I tried to make a minimal example for
you... I must have overseen something:

-----------
#include <iostream>
#include <iomanip /* for std::setfill(), std::setw() */
using namespace std;

int main(){
double d1 = 8.126e9;
// setw(5);

cout <<setw(5)<< "d1 = " << setprecision(1) << d1 << endl;
cout << "d1 = " << setprecision(1) << ios::scientific << d1 << endl;
return 0;
}

-----------
The above program prints:

d1 = 2568e+09

???? Where did that number come from?
You printed the value of "ios::scientific" in front of d1.
>
As said: My real program uses outfile:

outfile << " & " << setw(15) << twoDimens[i][j];

So once I know how how strip 3 characters from the output (after the
'e') I can implement it... Any suggestions?

Best regards
Martin Jørgensen

#include <iostream>
#include <ostream>
#include <iomanip /* for std::setfill(), std::setw() */

int main(){
std::ostringstream out;
out.setf( std::ios_base::scientific );
out.precision(1);

double d1 = 8.126e9;
out << d1;
std::string Num( out.str() );
cout<<"string Num = "<< Num <<std::endl;
// out: string Num = 8.1e+009

cout <<"d1 = "<< d1 <<std::endl;
// out: d1 = 8126000000.000000

cout <<out.str()<<std::endl;
// out: 8.1e+009

size_t pos(0);
if( ( pos = Num.find("+") ) != std::string::npos){
Num.erase( pos, 3 );
}
cout<<"string Num = "<< Num <<std::endl;
// out: string Num = 8.1e9 <<------ is that what you want

return 0;
} // main()

--
Bob R
POVrookie
Nov 5 '06 #3
BobR wrote:
Martin Jørgensen wrote in message
<45*********************@dread12.news.tele.dk>.. .
>>#include <iostream>
#include <iomanip /* for std::setfill(), std::setw() */
using namespace std;

int main(){
double d1 = 8.126e9;

// setw(5);

cout <<setw(5)<< "d1 = " << setprecision(1) << d1 << endl;
Ok, thanks.
> cout << "d1 = " << setprecision(1) << ios::scientific << d1 << endl;
return 0;
}

-----------
The above program prints:

d1 = 2568e+09

???? Where did that number come from?


You printed the value of "ios::scientific" in front of d1.
Oh, that has a value? Hmm. I just tried it, I think you're right. It has
the value 256... That makes sense...
>>As said: My real program uses outfile:

outfile << " & " << setw(15) << twoDimens[i][j];

So once I know how how strip 3 characters from the output (after the
'e') I can implement it... Any suggestions?

Best regards
Martin Jørgensen

#include <iostream>
#include <ostream>
#include <iomanip /* for std::setfill(), std::setw() */

int main(){
std::ostringstream out;
out.setf( std::ios_base::scientific );
out.precision(1);

double d1 = 8.126e9;
out << d1;
std::string Num( out.str() );
cout<<"string Num = "<< Num <<std::endl;
// out: string Num = 8.1e+009

cout <<"d1 = "<< d1 <<std::endl;
// out: d1 = 8126000000.000000

cout <<out.str()<<std::endl;
// out: 8.1e+009

size_t pos(0);
if( ( pos = Num.find("+") ) != std::string::npos){
Num.erase( pos, 3 );
}
cout<<"string Num = "<< Num <<std::endl;
// out: string Num = 8.1e9 <<------ is that what you want
Exactly!
return 0;
} // main()
If I ever came up with something that could do that, my solution would
probably be much uglier (and much more C-like)...

Btw: I changed it so it removes arbitrary number of 0's after the +. I
don't know if it's elegant (probably not) but it seem to work:
if( ( pos = Num.find("+") ) != std::string::npos) {
Num.erase( pos, 1 ); /* erase +-sign */

while( Num[pos] == '0' && pos != std::string::npos) {
Num.erase( pos, 1); /* erase all '0's */
pos++;
}
}

Thanks a lot for the hint. Now I can continue from where I was stuck :-)

It was actually a bit of an exercise to implement your hint (took almost
3 hours), but I think I made it now and it's nice to see when the work
pays off :-)
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Nov 5 '06 #4

Martin Jørgensen wrote in message ...
>BobR wrote:
>Martin Jørgensen wrote in message ...
>>>-----------
The above program prints:

d1 = 2568e+09

???? Where did that number come from?

You printed the value of "ios::scientific" in front of d1.

Oh, that has a value? Hmm. I just tried it, I think you're right. It has
the value 256... That makes sense...
<snip>
>>
#include <iostream>
#include <ostream>
#include <iomanip /* for std::setfill(), std::setw() */

int main(){
std::ostringstream out;
out.setf( std::ios_base::scientific );
out.precision(1);

double d1 = 8.126e9;
out << d1;
std::string Num( out.str() );
cout<<"string Num = "<< Num <<std::endl;
// out: string Num = 8.1e+009

cout <<"d1 = "<< d1 <<std::endl;
// out: d1 = 8126000000.000000

cout <<out.str()<<std::endl;
// out: 8.1e+009

size_t pos(0);
if( ( pos = Num.find("+") ) != std::string::npos){
Num.erase( pos, 3 );
}
cout<<"string Num = "<< Num <<std::endl;
// out: string Num = 8.1e9 <<------ is that what you want

Exactly!
> return 0;
} // main()

If I ever came up with something that could do that, my solution would
probably be much uglier (and much more C-like)...

Btw: I changed it so it removes arbitrary number of 0's after the +. I
don't know if it's elegant (probably not) but it seem to work:

if( ( pos = Num.find("+") ) != std::string::npos) {
Num.erase( pos, 1 ); /* erase +-sign */

while( Num[pos] == '0' && pos != std::string::npos) {
Num.erase( pos, 1); /* erase all '0's */
pos++;
}
}
Oh NOOoooo!!! std::string::npos is sometimes/usually a '-1'. That's a big
number in 'unsigned int' (assuming twos comp).

size_t Snpos( static_cast<size_t>( std::string::npos ));
std::cout<<" Snpos ="<<Snpos<<std::endl;
// output: Snpos =4294967295

What you want to compare to is the size of the string:

while( Num[pos] == '0' && pos < Num.size() ) {
Num.erase( pos, 1); /* erase all '0's */
pos++;
}

Also, I like to use the at() for index access when I'm not positive I'm in
range ( like in a dpr() loop):

try{
while( Num.at( pos ) == '0' && pos < Num.size() ) {
Num.erase( pos, 1); /* erase all '0's */
++pos;
}
} // try
catch(std::out_of_range &Oor){
std::cout<<"caught "<<Oor.what()<<std::endl;
}

--
Bob R
POVrookie
Nov 5 '06 #5
BobR wrote:
Martin Jørgensen wrote in message ...
-snip-
>>If I ever came up with something that could do that, my solution would
probably be much uglier (and much more C-like)...

Btw: I changed it so it removes arbitrary number of 0's after the +. I
don't know if it's elegant (probably not) but it seem to work:

if( ( pos = Num.find("+") ) != std::string::npos) {
Num.erase( pos, 1 ); /* erase +-sign */

while( Num[pos] == '0' && pos != std::string::npos) {
Num.erase( pos, 1); /* erase all '0's */
pos++;
}
}


Oh NOOoooo!!! std::string::npos is sometimes/usually a '-1'. That's a big
number in 'unsigned int' (assuming twos comp).
Oh, damn :-)

Thanks a lot for the correction...
size_t Snpos( static_cast<size_t>( std::string::npos ));
std::cout<<" Snpos ="<<Snpos<<std::endl;
// output: Snpos =4294967295

What you want to compare to is the size of the string:

while( Num[pos] == '0' && pos < Num.size() ) {
Num.erase( pos, 1); /* erase all '0's */
pos++;
}
Ok.
Also, I like to use the at() for index access when I'm not positive I'm in
range ( like in a dpr() loop):

try{
while( Num.at( pos ) == '0' && pos < Num.size() ) {
Num.erase( pos, 1); /* erase all '0's */
++pos;
Oh, that was also stupid of me.... While I tried your Num.at()
suggestion it occured to me that it was pretty strange it didn't work....

Then I figured out that ofcourse it's a mistake to increment "pos"
because the next number is already in the right position, when the
current "0" has been deleted.... :-(

But hopefully I won't make the same mistake next time I'll have to do
something similar :-)
}
} // try
catch(std::out_of_range &Oor){
std::cout<<"caught "<<Oor.what()<<std::endl;
}
Thanks again...
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Nov 5 '06 #6
BobR wrote:
-snip-

I just realized that there's a problem with the number: "0.000e+00"
which becomes: "0.000e" + an exception.... Here's my code:

-------
if( ( pos = exp_string.find("+") ) != std::string::npos) {
exp_string.erase( pos, 1 );

try {
while( exp_string.at( pos ) == '0' && pos < exp_string.size())
exp_string.erase( pos, 1 );
}
catch(std::out_of_range &Oor)
{
std::cout << endl << "Caught "<< Oor.what() << std::endl;
}
}
-------

But I just figured out that the try/while-line *must* say:

while( pos < exp_string.size() && exp_string.at( pos ) == '0')
Or else I get an exception... Very interesting.

But it makes completely sense because as soon as the first logical test
fails, it'll never try to figure out what the second gives.... So the
order really matters :-)
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Nov 5 '06 #7

Martin Jørgensen wrote in message
<45*********************@dread12.news.tele.dk>.. .
>BobR wrote:
-snip-

I just realized that there's a problem with the number: "0.000e+00"
which becomes: "0.000e" + an exception.... Here's my code:

-------
if( ( pos = exp_string.find("+") ) != std::string::npos) {
exp_string.erase( pos, 1 );
try {
while( exp_string.at( pos ) == '0' && pos < exp_string.size())
exp_string.erase( pos, 1 );
}
catch(std::out_of_range &Oor){
std::cout << endl << "Caught "<< Oor.what() << std::endl;
}
}
-------
But I just figured out that the try/while-line *must* say:

while( pos < exp_string.size() && exp_string.at( pos ) == '0')

Or else I get an exception... Very interesting.

But it makes completely sense because as soon as the first logical test
fails, it'll never try to figure out what the second gives.... So the
order really matters :-)
An if() in the while loop after the *.erase() would have prevented the
exception:

if( pos >= exp_string.size() ){ break; }

I almost didn't mention the *.at(). I guess that '++pos' was tugging at the
back of my mind. Pretty neat how that try/catch works, eh. I'm sure you would
have spent a long time looking for the bug without it.
Yeah, in my prior post I was in a big hurry[1]. I wanted to stop you before
you 'copy/paste'd that 'string::npos' code in 531 places, and then would have
to go back and correct it all. <G>

Hopefully you only use it one place, or have put it in a little helper
function.

You also stated that the doubles were all positive, so, I didn't code for '-'
or '0.0'.
[ I generally don't think of zero haveing a sign, but, 'stream' has a
different attitude. :-} ]

[1] - so I spotted errors after I posted. Grrrr!! <G>
--
Bob R
POVrookie
Nov 6 '06 #8
BobR wrote:
Martin Jørgensen wrote in message
<45*********************@dread12.news.tele.dk>.. .
>>BobR wrote:
-snip-

I just realized that there's a problem with the number: "0.000e+00"
which becomes: "0.000e" + an exception.... Here's my code:

-------
if( ( pos = exp_string.find("+") ) != std::string::npos) {
exp_string.erase( pos, 1 );
try {
while( exp_string.at( pos ) == '0' && pos < exp_string.size())
exp_string.erase( pos, 1 );
}
catch(std::out_of_range &Oor){
std::cout << endl << "Caught "<< Oor.what() << std::endl;
}
}
-------
But I just figured out that the try/while-line *must* say:

while( pos < exp_string.size() && exp_string.at( pos ) == '0')

Or else I get an exception... Very interesting.

But it makes completely sense because as soon as the first logical test
fails, it'll never try to figure out what the second gives.... So the
order really matters :-)


An if() in the while loop after the *.erase() would have prevented the
exception:

if( pos >= exp_string.size() ){ break; }
Agreed. I like the short formulation better:

while( pos < exp_string.size() && exp_string.at( pos ) == '0')

Because I then have 1 less line and still get the same effect (I
think)... I also hate those "break"'s inside loops, but I agree that
sometimes I can't avoid them so easily and when such a situation occurs
I've sometimes inserted a couple of breaks...

But it makes the code so ugly, I think :-)

In my bs.c. project which I handed in this summer (written in C) I also
used "goto" because I had a couple of for-loops and break wasn't enough
if I wanted to quit the inner-most for-loop and exit a couple of
for-loops completely... It was really really "ugly" :-)
I almost didn't mention the *.at(). I guess that '++pos' was tugging at the
back of my mind. Pretty neat how that try/catch works, eh. I'm sure you would
have spent a long time looking for the bug without it.
Yep! :-)
Yeah, in my prior post I was in a big hurry[1]. I wanted to stop you before
you 'copy/paste'd that 'string::npos' code in 531 places, and then would have
to go back and correct it all. <G>

Hopefully you only use it one place, or have put it in a little helper
function.
Yep, it's inside a function so I only use it 1 place...
You also stated that the doubles were all positive, so, I didn't code for '-'
or '0.0'.
Exactly.
[ I generally don't think of zero haveing a sign, but, 'stream' has a
different attitude. :-} ]

[1] - so I spotted errors after I posted. Grrrr!! <G>
IMHO the important thing is that I was stuck and got a bit of help to
continue on my own, so thanks a lot for that :-)
Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Nov 6 '06 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Gactimus | last post by:
I made the program below. It outputs the smallest number in the array. What I would like to know is how do I output the array location. I am at a loss. For example, since the smallest number in...
1
by: diegoandrade | last post by:
In this code the exponential part using scientific notation becomes e+002 is ther a way of changging the number of values after e so they can appear like e+02, only 2 values instead 3?? I have...
9
by: J.Sperlhofer | last post by:
Good morning, Javascript-Professionals. I'm looking for an possibility to show a (calculated) 64bit-Number without exponential notation. I don't want to see exponational notation within my...
9
by: ting | last post by:
I'm a newer in C++. I hope to output a string's address. The program is as follows: #include <iostream> using namespace std; int main() { char *str="ABCD"; char *p;
2
by: Rod Brick | last post by:
I'm trying to print a Double in straight decimal form, not exponential. I can't seem to accomplish this. This seems like it should be simple enough. The output I'm looking for is "0.00001", not...
9
by: malla | last post by:
Hi, I am trying to open a bunch of files and get data from them into one single file. I am sure this process can be automated if I name the files that I want to open in a regular pattern (say...
6
by: Xernoth | last post by:
Hi, I have an exercise that requests the following: Write a function that reads words from an input stream and stores them in a vector. Use that function both to write programs that count the...
8
by: Vasileios Zografos | last post by:
Hi, I am trying to output some numbers on the console (command prompt) using the std::cout command. If I do the following: for (int i=1;i<=10;i++) std::cout<<i; the output will be:
6
by: Ralf Goertz | last post by:
Hi, I'd like to use copy() to send the content of an integer container to cout. How can I make sure that /all/ of them are printed with width 2? #include <iostream> #include <iterator> int...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
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...

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.