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

Multi tool use
Multi tool use












1















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










share|improve this question

























  • 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


















1















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










share|improve this question

























  • 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
















1












1








1








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










share|improve this question
















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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





















  • 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














1 Answer
1






active

oldest

votes


















1














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 to err.




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 or HUGE_VALL is returned. If no conversion can be performed, ​0​ is returned and *str_end is set to str.




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.






share|improve this answer


























  • 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











  • 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











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
});


}
});














draft saved

draft discarded


















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









1














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 to err.




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 or HUGE_VALL is returned. If no conversion can be performed, ​0​ is returned and *str_end is set to str.




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.






share|improve this answer


























  • 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











  • 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
















1














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 to err.




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 or HUGE_VALL is returned. If no conversion can be performed, ​0​ is returned and *str_end is set to str.




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.






share|improve this answer


























  • 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











  • 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














1












1








1







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 to err.




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 or HUGE_VALL is returned. If no conversion can be performed, ​0​ is returned and *str_end is set to str.




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.






share|improve this answer















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 to err.




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 or HUGE_VALL is returned. If no conversion can be performed, ​0​ is returned and *str_end is set to str.




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.







share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 2 at 13:42

























answered Jan 2 at 12:26









YSCYSC

25k557112




25k557112













  • 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











  • 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











  • 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




















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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
hkxMKM EUqxYC,dv5oNoDROamkFlBkcWzEYUtV7x,volTKBC,4MWfPoeQtwsYlWeXgR

Popular posts from this blog

Monofisismo

Angular Downloading a file using contenturl with Basic Authentication

Olmecas