473,396 Members | 1,767 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,396 software developers and data experts.

string to double conversion - atof() vs istringstream

I need a conversion function that converts values from string to a
particular type. For this I have a template function that looks like
this ...

template<class T>
T value(const string& s)
{
istringstream(s);
T val;
is >val;
return val;
}

Now for double type the lowest positive value is 2.22507-308 and I get
different answers when I use this function vs atof() function. I am not
getting the reason here. Interestingly, if I reduce the exponent value
from -308 to -307, I get similar results.

Regards,
Harry.

Jul 25 '06 #1
14 8873
Forgot to mention this before. atof() behaviour is expected for -308
exp and that of istringstream is wrong.

Regards,
Harry.

sh**********@gmail.com wrote:
I need a conversion function that converts values from string to a
particular type. For this I have a template function that looks like
this ...

template<class T>
T value(const string& s)
{
istringstream(s);
T val;
is >val;
return val;
}

Now for double type the lowest positive value is 2.22507-308 and I get
different answers when I use this function vs atof() function. I am not
getting the reason here. Interestingly, if I reduce the exponent value
from -308 to -307, I get similar results.

Regards,
Harry.
Jul 25 '06 #2
sh**********@gmail.com wrote:
I need a conversion function that converts values from string to a
particular type. For this I have a template function that looks like
this ...

template<class T>
T value(const string& s)
{
istringstream(s);
T val;
is >val;
return val;
}

Now for double type the lowest positive value is 2.22507-308 and I get
different answers when I use this function vs atof() function. I am not
getting the reason here. Interestingly, if I reduce the exponent value
from -308 to -307, I get similar results.
How different are the results? Floating point numbers are notoriously
tricky. See, e.g., these FAQs:

http://www.parashift.com/c++-faq-lit...html#faq-29.16
http://www.parashift.com/c++-faq-lit...html#faq-29.18

Cheers! --M

Jul 25 '06 #3
On 24 Jul 2006 20:12:21 -0700, sh**********@gmail.com wrote:
>I need a conversion function that converts values from string to a
particular type. For this I have a template function that looks like
this ...

template<class T>
T value(const string& s)
{
istringstream(s);
T val;
is >val;
return val;
}
You don't check any return or error value in that function. Moreover,
I would prefer an explicit stringToDoulble() function to a template.
>Now for double type the lowest positive value is 2.22507-308 and I get
different answers when I use this function vs atof() function. I am not
getting the reason here. Interestingly, if I reduce the exponent value
from -308 to -307, I get similar results.
Use strtod
(http://www.opengroup.org/onlinepubs/...ns/strtod.html)
and check endptr, errno and return value.

Best wishes,
Roland Pibinger
Jul 25 '06 #4
Roland,
stringToDouble() is definitely something that will resolve the issue,
but that is not I am looking for. I was interested in minimizing the
no. of specialized functions that I write. Moreover, I am using this
only for the intrinsic types. As for the error checking, I don't know
how I can add that with the template types without specializing it for
a certain type.

Regards,
Harish Sharma
Roland Pibinger wrote:
On 24 Jul 2006 20:12:21 -0700, sh**********@gmail.com wrote:
I need a conversion function that converts values from string to a
particular type. For this I have a template function that looks like
this ...

template<class T>
T value(const string& s)
{
istringstream(s);
T val;
is >val;
return val;
}

You don't check any return or error value in that function. Moreover,
I would prefer an explicit stringToDoulble() function to a template.
Now for double type the lowest positive value is 2.22507-308 and I get
different answers when I use this function vs atof() function. I am not
getting the reason here. Interestingly, if I reduce the exponent value
from -308 to -307, I get similar results.

Use strtod
(http://www.opengroup.org/onlinepubs/...ns/strtod.html)
and check endptr, errno and return value.

Best wishes,
Roland Pibinger
Jul 26 '06 #5
mlimber,
The difference in the values is quite large to be neglected for a
rounding error as the faq says. And anyways I am not interested in
comparing any double type no.s here. The result that I get while using
this func is 2.64167e-308 while atof() returns 2.22507e-308. I
understand that atof() has minimal functionality and that too is type
specific, whereas the istringstream (or istream) has be generic.
However, I think the precision of default 6 digits is lost somewhere
while extracting the value from the string.

Regards,
Harish Sharma

mlimber wrote:
sh**********@gmail.com wrote:
I need a conversion function that converts values from string to a
particular type. For this I have a template function that looks like
this ...

template<class T>
T value(const string& s)
{
istringstream(s);
T val;
is >val;
return val;
}

Now for double type the lowest positive value is 2.22507-308 and I get
different answers when I use this function vs atof() function. I am not
getting the reason here. Interestingly, if I reduce the exponent value
from -308 to -307, I get similar results.

How different are the results? Floating point numbers are notoriously
tricky. See, e.g., these FAQs:

http://www.parashift.com/c++-faq-lit...html#faq-29.16
http://www.parashift.com/c++-faq-lit...html#faq-29.18

Cheers! --M
Jul 26 '06 #6
sh**********@gmail.com wrote:
Roland,
stringToDouble() is definitely something that will resolve the issue,

Please don't top-post. Your reply belongs following or interspersed
with properly trimmed quotes. See the newsgroup FAQ list:
<http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.4>


Brian
Jul 26 '06 #7
Roland Pibinger wrote:
On 24 Jul 2006 20:12:21 -0700, sh**********@gmail.com wrote:
I need a conversion function that converts values from string to a
particular type. For this I have a template function that looks like
this ...

template<class T>
T value(const string& s)
{
istringstream(s);
T val;
is >val;
return val;
}

You don't check any return or error value in that function.
That is a good point. Are you sure the conversion didn't abort
prematurely? Please post a *complete* but *minimal* program (see FAQ
5.8) that demonstrates your problem so we can reproduce it.

Cheers! --M

Jul 26 '06 #8
#include <iostream>
#include <sstream>
#include <cstdlib>

using namespace std;

template<class T>
T value(string s)
{
istringstream(s);
T val; is >val;
return val;
}

int
main()
{
cout << "\natof(2.22507e-308) ->" << atof("2.22507e-308");
cout << "\nvalue<double>(2.22507e-308) ->" <<
value<double>("2.22507e-308");
return 0;
}

Above is the complete demo program illustrating the problem. Actually
the value displayed by the template function is not consistent across
compilation and is sorta random (atleast I didn't see any pattern or
consistent values with every compilation). I checked the output with
MSVC as well as with GCC compiler. They give different values but
neither gives the right output.

Regards,
Harish Sharma

Jul 27 '06 #9
sh**********@gmail.com wrote:
#include <iostream>
#include <sstream>
#include <cstdlib>

using namespace std;

template<class T>
T value(string s)
{
istringstream(s);
T val; is >val;
return val;
}
Try this instead:

class MyException {};

template<class T>
T value(const string& s)
{
istringstream is(s);
T val;
if( !(is >val) || !(is >ws).eof() )
{
throw MyException();
}
return val;
}

Or better, use boost::lexical_cast, which does basically the same thing
'cept better. I get the same answer for both with the above code:

atof(2.22507e-308) ->2.22507e-308
value<double>(2.22507e-308) ->2.22507e-308
>
int
main()
{
cout << "\natof(2.22507e-308) ->" << atof("2.22507e-308");
cout << "\nvalue<double>(2.22507e-308) ->" <<
value<double>("2.22507e-308");
return 0;
}

Above is the complete demo program illustrating the problem. Actually
the value displayed by the template function is not consistent across
compilation and is sorta random (atleast I didn't see any pattern or
consistent values with every compilation). I checked the output with
MSVC as well as with GCC compiler. They give different values but
neither gives the right output.
That's probably because you forgot the variable name for the string
stream (it's using 's', which means you can't access the string that
was passed in and you have a global 'is' somewhere). GIGO.

Cheers! --M

Jul 27 '06 #10
mlimber,

I tried compiling the same program with a later ver of MS C/C++
compiler, which is ...
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42
for 80x86

With this compiler the test program gives expected results. But the GCC
compiler that I am using is gcc version 3.3.1 (mingw special
20030804-1), and it still gives out garbage. And by the way I believe,
there is no garbage i/p in the test program and hence there is no
question of GIGO. Moreover, I don't think there is any need of
exception handling in the test code with the given valid input and I
don't understand how that extra piece of error checking will help. If
your compiler/lib gives you expected results with the given input, it
should behave the same without that as well.

Another simple test to confirm the problem is,

int main() { double d; cin >d; cout << d; return 0; }

Just enter the value 2.22507-308 after compiling with your compiler and
it should show the expected result. But if you try this with the GCC
compiler version that I have mentioned, it gives out garbage. This
piece of code behaves similar to the earlier test program with both the
compilers that I used.

Lastly I tried your changes with GCC and it generates exception and
that tells me that there is some definite issue in the related version
of c++ lib that it is using.

Regards,
Harish Sharma

Jul 29 '06 #11
sh**********@gmail.com wrote:
if your compiler/lib gives you expected results with the given input, it
should behave the same without that as well.
I actually meant, if your compiler/lib gives you expected results with
the give input AND THE ERROR HANDLING CODE, it should behave the same
without that (error handling code) as well.

Regards,
Harish Sharma

Jul 29 '06 #12
sh**********@gmail.com wrote:
mlimber,

I tried compiling the same program with a later ver of MS C/C++
compiler, which is ...
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42
for 80x86

With this compiler the test program gives expected results. But the GCC
compiler that I am using is gcc version 3.3.1 (mingw special
20030804-1), and it still gives out garbage. And by the way I believe,
there is no garbage i/p in the test program and hence there is no
question of GIGO.
I used g++ 3.4.4 (cygming special) to build and run this program:

#include <iostream>
#include <iomanip>
#include <sstream>
#include <cstdlib>

using namespace std;

class MyException {};

template<class T>
T value(const string& s)
{
istringstream is(s);
T val;
if( !(is >val) || !(is >ws).eof() )
{
throw MyException();
}
return val;
}

int main()
{
cout << "atof(2.22507e-308) - "
<< atof("2.22507e-308") << '\n';
try
{
cout << "value<double>(2.22507e-308) ->"
<< value<double>("2.22507e-308");
}
catch( ... )
{
cout << "Caught exception.";
}
cout << endl;
}

It gives me the expected result. If it does not for you, then it is
likely a compiler/library problem, which you should ask about on
gnu.g++.help or similar.
Moreover, I don't think there is any need of
exception handling in the test code with the given valid input and I
don't understand how that extra piece of error checking will help. If
your compiler/lib gives you expected results with the given input, it
should behave the same without that as well.

Lastly I tried your changes with GCC and it generates exception and
that tells me that there is some definite issue in the related version
of c++ lib that it is using.
The exception handling is an alternate way of handling unexpected
errors to checking return values (cf.
http://www.parashift.com/c++-faq-lit...html#faq-17.1). In
this case, exceptions provide a way to indicate a failure without
having some sort of potentially invalid value (e.g., return FLOAT_MIN
on error or a std::pair<float,boolwhere the flag indicates validity)
being returned to the client, and the client can catch and handle such
an error at whatever level is appropriate. Anyway, the fact that you
get an exception seems to indicate that there was in fact an unexpected
error of some kind, so I think your claim that this sort of error
checking is unnecessary is self-defeating.

Cheers! --M

Jul 31 '06 #13
Anyway, the fact that you
get an exception seems to indicate that there was in fact an unexpected
error of some kind, so I think your claim that this sort of error
checking is unnecessary is self-defeating.
*self-defeating* ?

My comment on exception handling was not general and was specific to
the test code with the given *valid* input to the program.

Regards,
Harish Sharma

Aug 1 '06 #14
sh**********@gmail.com wrote:
I need a conversion function that converts values from string to a
particular type. For this I have a template function that looks like
this ...

template<class T>
T value(const string& s)
{
istringstream(s);
T val;
is >val;
return val;
}

Now for double type the lowest positive value is 2.22507-308 and I get
different answers when I use this function vs atof() function. I am not
getting the reason here. Interestingly, if I reduce the exponent value
from -308 to -307, I get similar results.
atof() causes undefined behaviour if the result isn't representable
as a double. Change to strtod() instead of atof(), and see if you
still get the same problem.

Aug 1 '06 #15

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

Similar topics

2
by: Miki Tebeka | last post by:
Hello All, I'm shipping an application using py2exe. With Python2.3 it worked fine but when switching to Python2.4 I started getting "warning: string/unicode conversion" all over the place. ...
1
by: kaede | last post by:
Hi all, Given the following data format: { "(1,2), "(2.5, 3.5)", .... } I would like to define a vector<string> to stored this data: v = "(1,2)", v = "(2.5, 3.5"), .... and would like to...
9
by: el_boricua | last post by:
What is the best way to convert from a string to a int and from a string to double? I have a line that is tokenize and I need to parse to test the tokens and convert them to their respective values...
4
by: Matt | last post by:
Hi there, I'm having a weird situation when converting strings to double. Normally, the following code would work right? double MyDouble = double.Parse("20.50"); // Error at runtime Well,...
3
by: Herb Stevenson | last post by:
Hello. I have a very large string reprentation of a number, for example "1000001002003004005006007008009010". If I user Double.Parse, I get something like 1.0000010020030041E+33 as my output. I...
2
by: Bit Byte | last post by:
I want to parse a string (actually a date [always in the format 'YYYYMMDD') into integer values like this: void parseDate(const string&sdate, int& day, int& mon, int &year) { istringstream...
5
oll3i
by: oll3i | last post by:
public class Cennik { private static Cennik instance = null; Map<String,Double> cennik = new HashMap<String,Double> (); private Cennik() { // prywatny konstruktor } public...
1
by: krishna81m | last post by:
I am a newbie and have been trying to understand conversion from double to int and then back to int using the following code was posted on the c++ google group. Could someone help me out with...
5
by: Evyn | last post by:
Hi all, I have recently asked for advice: http://groups.google.com/group/comp.lang.c++/browse_thread/thread/1b42e6855a2c571b/e63d8f10b51f015c?lnk=raot#e63d8f10b51f015c My task is to convert a...
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: 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?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.