Why std::istringstream generates wrong results without raising the failbit flag?

Multi tool use
When I convert a string
that contains long double
to float
or double
, std::istringstream
doesn't raise the failbit flag in QNX.
The following is a demonstration code:
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <limits>
int main(){
const long double originaldNumber = std::numeric_limits<long double>::max() / 2;
float floatNumber;
std::string numberString = std::to_string(originaldNumber);
//From string to long double
std::istringstream iss(numberString);
iss >> floatNumber;
if (iss.fail())
std::cout<< "iss failed n";
std::cout<< std::setprecision(30) << originaldNumber << "n";
std::cout<< std::setprecision(30) << floatNumber << "n";
return 0;
}
The output in linux is:
iss failed
5.94865747678615882510631926515e+4931
3.40282346638528859811704183485e+38
The output in QNX is:
5.94865747678615882510631e+4931
inf
QNX version: 7.0.3 2018/09/18-00:28:50EDT x86pc x86_64
.
Toolchain: gcc_ntox86_64
c++ string stream floating-point qnx
add a comment |
When I convert a string
that contains long double
to float
or double
, std::istringstream
doesn't raise the failbit flag in QNX.
The following is a demonstration code:
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <limits>
int main(){
const long double originaldNumber = std::numeric_limits<long double>::max() / 2;
float floatNumber;
std::string numberString = std::to_string(originaldNumber);
//From string to long double
std::istringstream iss(numberString);
iss >> floatNumber;
if (iss.fail())
std::cout<< "iss failed n";
std::cout<< std::setprecision(30) << originaldNumber << "n";
std::cout<< std::setprecision(30) << floatNumber << "n";
return 0;
}
The output in linux is:
iss failed
5.94865747678615882510631926515e+4931
3.40282346638528859811704183485e+38
The output in QNX is:
5.94865747678615882510631e+4931
inf
QNX version: 7.0.3 2018/09/18-00:28:50EDT x86pc x86_64
.
Toolchain: gcc_ntox86_64
c++ string stream floating-point qnx
Please specify what the toolchain is, including version.
– Lightness Races in Orbit
Jan 2 at 11:46
I use this: QCC -V5.4.0,gcc_ntox86_64 main.cpp -o qnxTest -std=gnu++14. My version: QNX localhost 7.0.3 2018/09/18-00:28:50EDT x86pc x86_64
– I. Hamad
Jan 2 at 11:49
add a comment |
When I convert a string
that contains long double
to float
or double
, std::istringstream
doesn't raise the failbit flag in QNX.
The following is a demonstration code:
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <limits>
int main(){
const long double originaldNumber = std::numeric_limits<long double>::max() / 2;
float floatNumber;
std::string numberString = std::to_string(originaldNumber);
//From string to long double
std::istringstream iss(numberString);
iss >> floatNumber;
if (iss.fail())
std::cout<< "iss failed n";
std::cout<< std::setprecision(30) << originaldNumber << "n";
std::cout<< std::setprecision(30) << floatNumber << "n";
return 0;
}
The output in linux is:
iss failed
5.94865747678615882510631926515e+4931
3.40282346638528859811704183485e+38
The output in QNX is:
5.94865747678615882510631e+4931
inf
QNX version: 7.0.3 2018/09/18-00:28:50EDT x86pc x86_64
.
Toolchain: gcc_ntox86_64
c++ string stream floating-point qnx
When I convert a string
that contains long double
to float
or double
, std::istringstream
doesn't raise the failbit flag in QNX.
The following is a demonstration code:
#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
#include <limits>
int main(){
const long double originaldNumber = std::numeric_limits<long double>::max() / 2;
float floatNumber;
std::string numberString = std::to_string(originaldNumber);
//From string to long double
std::istringstream iss(numberString);
iss >> floatNumber;
if (iss.fail())
std::cout<< "iss failed n";
std::cout<< std::setprecision(30) << originaldNumber << "n";
std::cout<< std::setprecision(30) << floatNumber << "n";
return 0;
}
The output in linux is:
iss failed
5.94865747678615882510631926515e+4931
3.40282346638528859811704183485e+38
The output in QNX is:
5.94865747678615882510631e+4931
inf
QNX version: 7.0.3 2018/09/18-00:28:50EDT x86pc x86_64
.
Toolchain: gcc_ntox86_64
c++ string stream floating-point qnx
c++ string stream floating-point qnx
edited Jan 2 at 11:51
I. Hamad
asked Jan 2 at 11:30
I. HamadI. Hamad
17211
17211
Please specify what the toolchain is, including version.
– Lightness Races in Orbit
Jan 2 at 11:46
I use this: QCC -V5.4.0,gcc_ntox86_64 main.cpp -o qnxTest -std=gnu++14. My version: QNX localhost 7.0.3 2018/09/18-00:28:50EDT x86pc x86_64
– I. Hamad
Jan 2 at 11:49
add a comment |
Please specify what the toolchain is, including version.
– Lightness Races in Orbit
Jan 2 at 11:46
I use this: QCC -V5.4.0,gcc_ntox86_64 main.cpp -o qnxTest -std=gnu++14. My version: QNX localhost 7.0.3 2018/09/18-00:28:50EDT x86pc x86_64
– I. Hamad
Jan 2 at 11:49
Please specify what the toolchain is, including version.
– Lightness Races in Orbit
Jan 2 at 11:46
Please specify what the toolchain is, including version.
– Lightness Races in Orbit
Jan 2 at 11:46
I use this: QCC -V5.4.0,gcc_ntox86_64 main.cpp -o qnxTest -std=gnu++14. My version: QNX localhost 7.0.3 2018/09/18-00:28:50EDT x86pc x86_64
– I. Hamad
Jan 2 at 11:49
I use this: QCC -V5.4.0,gcc_ntox86_64 main.cpp -o qnxTest -std=gnu++14. My version: QNX localhost 7.0.3 2018/09/18-00:28:50EDT x86pc x86_64
– I. Hamad
Jan 2 at 11:49
add a comment |
1 Answer
1
active
oldest
votes
According to cppreference.com, here is what happen:
std::istringstream::operator<<(float&)
:
(5) extracts a floating point value by calling
std::num_get::get()
std::num_get::get()
Stage 3: conversion and storage
The input is parsed as if by
std::strtof
In any case, if the conversion function fails
std::ios_base::failbit
is assigned toerr
.
std::strtof
Return value
Floating point value corresponding to the contents of str on success. If the converted value falls out of range of corresponding return type, range error occurs and
HUGE_VAL
,HUGE_VALF
orHUGE_VALL
is returned. If no conversion can be performed, 0 is returned and*str_end
is set tostr
.
HUGE_VALF
HUGE_VALF
Expands to positive float expression that indicates overflow
In your case, it is clear that std::strtof
with 5.94...e+4931
will overflow a float
, it should return HUGE_VALF
, which is an error value for this function. Under linux:
float const have_overflown = std::strtof("1e307", nullptr);
std::cout << "equals HUGE_VALF: " << std::boolalpha
<< (have_overflown == HUGE_VALF) << 'n'; // true
std::cout << "string repr: " << have_overflown << 'n'; // inf
Live demo
Since std::strtof
effectively returns HUGE_VALF
for overflowing values, the failbit of a stream calling it should be set, as mandated in the spec of std::istringstream::operator<<(float&)
.
QNX fails this requirement. You could try and check where in the chain it fails.
According to QNX doc on strtof
:
If the correct value would cause overflow, plus or minus HUGE_VAL is returned according to the sign, and errno is set to ERANGE.
You could check errno
against ERANGE
in addition to checking the stream failbit:
errno = 0;
iss >> floatNumber;
if (iss.fail() || errno == ERANGE) {
// fail
}
Finally, if your implementation fails to conform to its own documentation as you say id does in the comment section, you could check floatNumber
against HUGE_VALF
to detect overflows.
thanks for the hint. For unknown reasonserrno
is not changed. In QNXerrno = 0
, in Linuxerrno=34
– I. Hamad
Jan 2 at 13:39
Report the bug to your vendor. See edit also.
– YSC
Jan 2 at 13:41
Yes I will do. Thanks for your support.
– I. Hamad
Jan 2 at 13:47
@H.Ilyas FYI It's kind of customary on SO to add a link to the bug report if it is publicly visible. You can write your own answer to the question and update it if it is solved one day.
– YSC
Jan 2 at 13:53
Yes I will put my answer if it is solved :)
– I. Hamad
Jan 2 at 14:30
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54005536%2fwhy-stdistringstream-generates-wrong-results-without-raising-the-failbit-flag%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
According to cppreference.com, here is what happen:
std::istringstream::operator<<(float&)
:
(5) extracts a floating point value by calling
std::num_get::get()
std::num_get::get()
Stage 3: conversion and storage
The input is parsed as if by
std::strtof
In any case, if the conversion function fails
std::ios_base::failbit
is assigned toerr
.
std::strtof
Return value
Floating point value corresponding to the contents of str on success. If the converted value falls out of range of corresponding return type, range error occurs and
HUGE_VAL
,HUGE_VALF
orHUGE_VALL
is returned. If no conversion can be performed, 0 is returned and*str_end
is set tostr
.
HUGE_VALF
HUGE_VALF
Expands to positive float expression that indicates overflow
In your case, it is clear that std::strtof
with 5.94...e+4931
will overflow a float
, it should return HUGE_VALF
, which is an error value for this function. Under linux:
float const have_overflown = std::strtof("1e307", nullptr);
std::cout << "equals HUGE_VALF: " << std::boolalpha
<< (have_overflown == HUGE_VALF) << 'n'; // true
std::cout << "string repr: " << have_overflown << 'n'; // inf
Live demo
Since std::strtof
effectively returns HUGE_VALF
for overflowing values, the failbit of a stream calling it should be set, as mandated in the spec of std::istringstream::operator<<(float&)
.
QNX fails this requirement. You could try and check where in the chain it fails.
According to QNX doc on strtof
:
If the correct value would cause overflow, plus or minus HUGE_VAL is returned according to the sign, and errno is set to ERANGE.
You could check errno
against ERANGE
in addition to checking the stream failbit:
errno = 0;
iss >> floatNumber;
if (iss.fail() || errno == ERANGE) {
// fail
}
Finally, if your implementation fails to conform to its own documentation as you say id does in the comment section, you could check floatNumber
against HUGE_VALF
to detect overflows.
thanks for the hint. For unknown reasonserrno
is not changed. In QNXerrno = 0
, in Linuxerrno=34
– I. Hamad
Jan 2 at 13:39
Report the bug to your vendor. See edit also.
– YSC
Jan 2 at 13:41
Yes I will do. Thanks for your support.
– I. Hamad
Jan 2 at 13:47
@H.Ilyas FYI It's kind of customary on SO to add a link to the bug report if it is publicly visible. You can write your own answer to the question and update it if it is solved one day.
– YSC
Jan 2 at 13:53
Yes I will put my answer if it is solved :)
– I. Hamad
Jan 2 at 14:30
add a comment |
According to cppreference.com, here is what happen:
std::istringstream::operator<<(float&)
:
(5) extracts a floating point value by calling
std::num_get::get()
std::num_get::get()
Stage 3: conversion and storage
The input is parsed as if by
std::strtof
In any case, if the conversion function fails
std::ios_base::failbit
is assigned toerr
.
std::strtof
Return value
Floating point value corresponding to the contents of str on success. If the converted value falls out of range of corresponding return type, range error occurs and
HUGE_VAL
,HUGE_VALF
orHUGE_VALL
is returned. If no conversion can be performed, 0 is returned and*str_end
is set tostr
.
HUGE_VALF
HUGE_VALF
Expands to positive float expression that indicates overflow
In your case, it is clear that std::strtof
with 5.94...e+4931
will overflow a float
, it should return HUGE_VALF
, which is an error value for this function. Under linux:
float const have_overflown = std::strtof("1e307", nullptr);
std::cout << "equals HUGE_VALF: " << std::boolalpha
<< (have_overflown == HUGE_VALF) << 'n'; // true
std::cout << "string repr: " << have_overflown << 'n'; // inf
Live demo
Since std::strtof
effectively returns HUGE_VALF
for overflowing values, the failbit of a stream calling it should be set, as mandated in the spec of std::istringstream::operator<<(float&)
.
QNX fails this requirement. You could try and check where in the chain it fails.
According to QNX doc on strtof
:
If the correct value would cause overflow, plus or minus HUGE_VAL is returned according to the sign, and errno is set to ERANGE.
You could check errno
against ERANGE
in addition to checking the stream failbit:
errno = 0;
iss >> floatNumber;
if (iss.fail() || errno == ERANGE) {
// fail
}
Finally, if your implementation fails to conform to its own documentation as you say id does in the comment section, you could check floatNumber
against HUGE_VALF
to detect overflows.
thanks for the hint. For unknown reasonserrno
is not changed. In QNXerrno = 0
, in Linuxerrno=34
– I. Hamad
Jan 2 at 13:39
Report the bug to your vendor. See edit also.
– YSC
Jan 2 at 13:41
Yes I will do. Thanks for your support.
– I. Hamad
Jan 2 at 13:47
@H.Ilyas FYI It's kind of customary on SO to add a link to the bug report if it is publicly visible. You can write your own answer to the question and update it if it is solved one day.
– YSC
Jan 2 at 13:53
Yes I will put my answer if it is solved :)
– I. Hamad
Jan 2 at 14:30
add a comment |
According to cppreference.com, here is what happen:
std::istringstream::operator<<(float&)
:
(5) extracts a floating point value by calling
std::num_get::get()
std::num_get::get()
Stage 3: conversion and storage
The input is parsed as if by
std::strtof
In any case, if the conversion function fails
std::ios_base::failbit
is assigned toerr
.
std::strtof
Return value
Floating point value corresponding to the contents of str on success. If the converted value falls out of range of corresponding return type, range error occurs and
HUGE_VAL
,HUGE_VALF
orHUGE_VALL
is returned. If no conversion can be performed, 0 is returned and*str_end
is set tostr
.
HUGE_VALF
HUGE_VALF
Expands to positive float expression that indicates overflow
In your case, it is clear that std::strtof
with 5.94...e+4931
will overflow a float
, it should return HUGE_VALF
, which is an error value for this function. Under linux:
float const have_overflown = std::strtof("1e307", nullptr);
std::cout << "equals HUGE_VALF: " << std::boolalpha
<< (have_overflown == HUGE_VALF) << 'n'; // true
std::cout << "string repr: " << have_overflown << 'n'; // inf
Live demo
Since std::strtof
effectively returns HUGE_VALF
for overflowing values, the failbit of a stream calling it should be set, as mandated in the spec of std::istringstream::operator<<(float&)
.
QNX fails this requirement. You could try and check where in the chain it fails.
According to QNX doc on strtof
:
If the correct value would cause overflow, plus or minus HUGE_VAL is returned according to the sign, and errno is set to ERANGE.
You could check errno
against ERANGE
in addition to checking the stream failbit:
errno = 0;
iss >> floatNumber;
if (iss.fail() || errno == ERANGE) {
// fail
}
Finally, if your implementation fails to conform to its own documentation as you say id does in the comment section, you could check floatNumber
against HUGE_VALF
to detect overflows.
According to cppreference.com, here is what happen:
std::istringstream::operator<<(float&)
:
(5) extracts a floating point value by calling
std::num_get::get()
std::num_get::get()
Stage 3: conversion and storage
The input is parsed as if by
std::strtof
In any case, if the conversion function fails
std::ios_base::failbit
is assigned toerr
.
std::strtof
Return value
Floating point value corresponding to the contents of str on success. If the converted value falls out of range of corresponding return type, range error occurs and
HUGE_VAL
,HUGE_VALF
orHUGE_VALL
is returned. If no conversion can be performed, 0 is returned and*str_end
is set tostr
.
HUGE_VALF
HUGE_VALF
Expands to positive float expression that indicates overflow
In your case, it is clear that std::strtof
with 5.94...e+4931
will overflow a float
, it should return HUGE_VALF
, which is an error value for this function. Under linux:
float const have_overflown = std::strtof("1e307", nullptr);
std::cout << "equals HUGE_VALF: " << std::boolalpha
<< (have_overflown == HUGE_VALF) << 'n'; // true
std::cout << "string repr: " << have_overflown << 'n'; // inf
Live demo
Since std::strtof
effectively returns HUGE_VALF
for overflowing values, the failbit of a stream calling it should be set, as mandated in the spec of std::istringstream::operator<<(float&)
.
QNX fails this requirement. You could try and check where in the chain it fails.
According to QNX doc on strtof
:
If the correct value would cause overflow, plus or minus HUGE_VAL is returned according to the sign, and errno is set to ERANGE.
You could check errno
against ERANGE
in addition to checking the stream failbit:
errno = 0;
iss >> floatNumber;
if (iss.fail() || errno == ERANGE) {
// fail
}
Finally, if your implementation fails to conform to its own documentation as you say id does in the comment section, you could check floatNumber
against HUGE_VALF
to detect overflows.
edited Jan 2 at 13:42
answered Jan 2 at 12:26


YSCYSC
25k557112
25k557112
thanks for the hint. For unknown reasonserrno
is not changed. In QNXerrno = 0
, in Linuxerrno=34
– I. Hamad
Jan 2 at 13:39
Report the bug to your vendor. See edit also.
– YSC
Jan 2 at 13:41
Yes I will do. Thanks for your support.
– I. Hamad
Jan 2 at 13:47
@H.Ilyas FYI It's kind of customary on SO to add a link to the bug report if it is publicly visible. You can write your own answer to the question and update it if it is solved one day.
– YSC
Jan 2 at 13:53
Yes I will put my answer if it is solved :)
– I. Hamad
Jan 2 at 14:30
add a comment |
thanks for the hint. For unknown reasonserrno
is not changed. In QNXerrno = 0
, in Linuxerrno=34
– I. Hamad
Jan 2 at 13:39
Report the bug to your vendor. See edit also.
– YSC
Jan 2 at 13:41
Yes I will do. Thanks for your support.
– I. Hamad
Jan 2 at 13:47
@H.Ilyas FYI It's kind of customary on SO to add a link to the bug report if it is publicly visible. You can write your own answer to the question and update it if it is solved one day.
– YSC
Jan 2 at 13:53
Yes I will put my answer if it is solved :)
– I. Hamad
Jan 2 at 14:30
thanks for the hint. For unknown reasons
errno
is not changed. In QNX errno = 0
, in Linux errno=34
– I. Hamad
Jan 2 at 13:39
thanks for the hint. For unknown reasons
errno
is not changed. In QNX errno = 0
, in Linux errno=34
– I. Hamad
Jan 2 at 13:39
Report the bug to your vendor. See edit also.
– YSC
Jan 2 at 13:41
Report the bug to your vendor. See edit also.
– YSC
Jan 2 at 13:41
Yes I will do. Thanks for your support.
– I. Hamad
Jan 2 at 13:47
Yes I will do. Thanks for your support.
– I. Hamad
Jan 2 at 13:47
@H.Ilyas FYI It's kind of customary on SO to add a link to the bug report if it is publicly visible. You can write your own answer to the question and update it if it is solved one day.
– YSC
Jan 2 at 13:53
@H.Ilyas FYI It's kind of customary on SO to add a link to the bug report if it is publicly visible. You can write your own answer to the question and update it if it is solved one day.
– YSC
Jan 2 at 13:53
Yes I will put my answer if it is solved :)
– I. Hamad
Jan 2 at 14:30
Yes I will put my answer if it is solved :)
– I. Hamad
Jan 2 at 14:30
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54005536%2fwhy-stdistringstream-generates-wrong-results-without-raising-the-failbit-flag%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
K8i0OTKG
Please specify what the toolchain is, including version.
– Lightness Races in Orbit
Jan 2 at 11:46
I use this: QCC -V5.4.0,gcc_ntox86_64 main.cpp -o qnxTest -std=gnu++14. My version: QNX localhost 7.0.3 2018/09/18-00:28:50EDT x86pc x86_64
– I. Hamad
Jan 2 at 11:49