Explicit specification of the double precision representation used by compiler











up vote
4
down vote

favorite












I've recently come across the problem that visual-c++ does not seem to be IEEE 754 compliant, but instead uses subnormal representation. That is, double precision floats in it do not have the usual representation of 1 sign bit, 11 exponent bits and 52 explicitly stored significant decimal bits, see below.





As gcc and clang are however compliant and consistent cross-platform behaviour is highly desired I would like to know whether it is possible to force visual-c++ to use the normal representation. Alternatively making gcc and clang use the subnormal representation would of course also solve the problem.



The issue of the different double representations can be reproduced in visual-c++, gcc and clang using the following code:



#include <iostream>
#include <string>

int main()
{
try {
std::stod("8.0975711886543594e-324");
std::cout << "Subnormal representation.";
} catch (std::exception& e) {
std::cout << "Normal representation.";
}
return 0;
}


Is a representation specification to produce consitent behaviour in all three cases at all possible?



Edit: As geza pointed out, this appears a problem in the different implementations of std::stod, which would then make the question if there is any way to make std::stod behave consistently without having to implement a seperate wrapper for it.










share|improve this question




















  • 1




    Here, the difference lies in std::stod, doesn't it? GCC and clang throw out_of_range for subnormal numbers (which is weird, if you ask me), while msvc doesn't. I even don't understand, why they throw out_of_range for a small number which is truncated to zero. It's definitely not out_of_range. There should be a separate exception for this case.
    – geza
    Nov 19 at 13:39










  • Relevant: stackoverflow.com/questions/48086830/…
    – geza
    Nov 19 at 13:45






  • 1




    std::stod is badly designed. strtod can report whether the ERANGE means overflow or underflow. std::stod cannot.
    – geza
    Nov 19 at 13:48










  • @geza Thanks, edited the post to reflect that its std::stod, maybe there's some standard way around the design
    – abcalphabet
    Nov 19 at 13:49










  • Yes, use strtod, which doesn't have this limitation. It behaves not as documented for subnormal numbers: it will return the subnormal value (so, contrary to the doc, it returns a non-zero value, yet sets errno=ERANGE). Which is good for us, because you can get the number you want.
    – geza
    Nov 19 at 13:53

















up vote
4
down vote

favorite












I've recently come across the problem that visual-c++ does not seem to be IEEE 754 compliant, but instead uses subnormal representation. That is, double precision floats in it do not have the usual representation of 1 sign bit, 11 exponent bits and 52 explicitly stored significant decimal bits, see below.





As gcc and clang are however compliant and consistent cross-platform behaviour is highly desired I would like to know whether it is possible to force visual-c++ to use the normal representation. Alternatively making gcc and clang use the subnormal representation would of course also solve the problem.



The issue of the different double representations can be reproduced in visual-c++, gcc and clang using the following code:



#include <iostream>
#include <string>

int main()
{
try {
std::stod("8.0975711886543594e-324");
std::cout << "Subnormal representation.";
} catch (std::exception& e) {
std::cout << "Normal representation.";
}
return 0;
}


Is a representation specification to produce consitent behaviour in all three cases at all possible?



Edit: As geza pointed out, this appears a problem in the different implementations of std::stod, which would then make the question if there is any way to make std::stod behave consistently without having to implement a seperate wrapper for it.










share|improve this question




















  • 1




    Here, the difference lies in std::stod, doesn't it? GCC and clang throw out_of_range for subnormal numbers (which is weird, if you ask me), while msvc doesn't. I even don't understand, why they throw out_of_range for a small number which is truncated to zero. It's definitely not out_of_range. There should be a separate exception for this case.
    – geza
    Nov 19 at 13:39










  • Relevant: stackoverflow.com/questions/48086830/…
    – geza
    Nov 19 at 13:45






  • 1




    std::stod is badly designed. strtod can report whether the ERANGE means overflow or underflow. std::stod cannot.
    – geza
    Nov 19 at 13:48










  • @geza Thanks, edited the post to reflect that its std::stod, maybe there's some standard way around the design
    – abcalphabet
    Nov 19 at 13:49










  • Yes, use strtod, which doesn't have this limitation. It behaves not as documented for subnormal numbers: it will return the subnormal value (so, contrary to the doc, it returns a non-zero value, yet sets errno=ERANGE). Which is good for us, because you can get the number you want.
    – geza
    Nov 19 at 13:53















up vote
4
down vote

favorite









up vote
4
down vote

favorite











I've recently come across the problem that visual-c++ does not seem to be IEEE 754 compliant, but instead uses subnormal representation. That is, double precision floats in it do not have the usual representation of 1 sign bit, 11 exponent bits and 52 explicitly stored significant decimal bits, see below.





As gcc and clang are however compliant and consistent cross-platform behaviour is highly desired I would like to know whether it is possible to force visual-c++ to use the normal representation. Alternatively making gcc and clang use the subnormal representation would of course also solve the problem.



The issue of the different double representations can be reproduced in visual-c++, gcc and clang using the following code:



#include <iostream>
#include <string>

int main()
{
try {
std::stod("8.0975711886543594e-324");
std::cout << "Subnormal representation.";
} catch (std::exception& e) {
std::cout << "Normal representation.";
}
return 0;
}


Is a representation specification to produce consitent behaviour in all three cases at all possible?



Edit: As geza pointed out, this appears a problem in the different implementations of std::stod, which would then make the question if there is any way to make std::stod behave consistently without having to implement a seperate wrapper for it.










share|improve this question















I've recently come across the problem that visual-c++ does not seem to be IEEE 754 compliant, but instead uses subnormal representation. That is, double precision floats in it do not have the usual representation of 1 sign bit, 11 exponent bits and 52 explicitly stored significant decimal bits, see below.





As gcc and clang are however compliant and consistent cross-platform behaviour is highly desired I would like to know whether it is possible to force visual-c++ to use the normal representation. Alternatively making gcc and clang use the subnormal representation would of course also solve the problem.



The issue of the different double representations can be reproduced in visual-c++, gcc and clang using the following code:



#include <iostream>
#include <string>

int main()
{
try {
std::stod("8.0975711886543594e-324");
std::cout << "Subnormal representation.";
} catch (std::exception& e) {
std::cout << "Normal representation.";
}
return 0;
}


Is a representation specification to produce consitent behaviour in all three cases at all possible?



Edit: As geza pointed out, this appears a problem in the different implementations of std::stod, which would then make the question if there is any way to make std::stod behave consistently without having to implement a seperate wrapper for it.







c++ gcc visual-c++ clang






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 at 13:49

























asked Nov 19 at 13:21









abcalphabet

4081213




4081213








  • 1




    Here, the difference lies in std::stod, doesn't it? GCC and clang throw out_of_range for subnormal numbers (which is weird, if you ask me), while msvc doesn't. I even don't understand, why they throw out_of_range for a small number which is truncated to zero. It's definitely not out_of_range. There should be a separate exception for this case.
    – geza
    Nov 19 at 13:39










  • Relevant: stackoverflow.com/questions/48086830/…
    – geza
    Nov 19 at 13:45






  • 1




    std::stod is badly designed. strtod can report whether the ERANGE means overflow or underflow. std::stod cannot.
    – geza
    Nov 19 at 13:48










  • @geza Thanks, edited the post to reflect that its std::stod, maybe there's some standard way around the design
    – abcalphabet
    Nov 19 at 13:49










  • Yes, use strtod, which doesn't have this limitation. It behaves not as documented for subnormal numbers: it will return the subnormal value (so, contrary to the doc, it returns a non-zero value, yet sets errno=ERANGE). Which is good for us, because you can get the number you want.
    – geza
    Nov 19 at 13:53
















  • 1




    Here, the difference lies in std::stod, doesn't it? GCC and clang throw out_of_range for subnormal numbers (which is weird, if you ask me), while msvc doesn't. I even don't understand, why they throw out_of_range for a small number which is truncated to zero. It's definitely not out_of_range. There should be a separate exception for this case.
    – geza
    Nov 19 at 13:39










  • Relevant: stackoverflow.com/questions/48086830/…
    – geza
    Nov 19 at 13:45






  • 1




    std::stod is badly designed. strtod can report whether the ERANGE means overflow or underflow. std::stod cannot.
    – geza
    Nov 19 at 13:48










  • @geza Thanks, edited the post to reflect that its std::stod, maybe there's some standard way around the design
    – abcalphabet
    Nov 19 at 13:49










  • Yes, use strtod, which doesn't have this limitation. It behaves not as documented for subnormal numbers: it will return the subnormal value (so, contrary to the doc, it returns a non-zero value, yet sets errno=ERANGE). Which is good for us, because you can get the number you want.
    – geza
    Nov 19 at 13:53










1




1




Here, the difference lies in std::stod, doesn't it? GCC and clang throw out_of_range for subnormal numbers (which is weird, if you ask me), while msvc doesn't. I even don't understand, why they throw out_of_range for a small number which is truncated to zero. It's definitely not out_of_range. There should be a separate exception for this case.
– geza
Nov 19 at 13:39




Here, the difference lies in std::stod, doesn't it? GCC and clang throw out_of_range for subnormal numbers (which is weird, if you ask me), while msvc doesn't. I even don't understand, why they throw out_of_range for a small number which is truncated to zero. It's definitely not out_of_range. There should be a separate exception for this case.
– geza
Nov 19 at 13:39












Relevant: stackoverflow.com/questions/48086830/…
– geza
Nov 19 at 13:45




Relevant: stackoverflow.com/questions/48086830/…
– geza
Nov 19 at 13:45




1




1




std::stod is badly designed. strtod can report whether the ERANGE means overflow or underflow. std::stod cannot.
– geza
Nov 19 at 13:48




std::stod is badly designed. strtod can report whether the ERANGE means overflow or underflow. std::stod cannot.
– geza
Nov 19 at 13:48












@geza Thanks, edited the post to reflect that its std::stod, maybe there's some standard way around the design
– abcalphabet
Nov 19 at 13:49




@geza Thanks, edited the post to reflect that its std::stod, maybe there's some standard way around the design
– abcalphabet
Nov 19 at 13:49












Yes, use strtod, which doesn't have this limitation. It behaves not as documented for subnormal numbers: it will return the subnormal value (so, contrary to the doc, it returns a non-zero value, yet sets errno=ERANGE). Which is good for us, because you can get the number you want.
– geza
Nov 19 at 13:53






Yes, use strtod, which doesn't have this limitation. It behaves not as documented for subnormal numbers: it will return the subnormal value (so, contrary to the doc, it returns a non-zero value, yet sets errno=ERANGE). Which is good for us, because you can get the number you want.
– geza
Nov 19 at 13:53














1 Answer
1






active

oldest

votes

















up vote
3
down vote



accepted










Unfortunately, std::stod is badly designed, because it is not possible to determine what caused the std::out_of_range exception.



I'd suggest you to use strtod instead. While is not specified in the standard what this function should do for subnormal numbers, it behaves well for subnormal numbers usually (it means that it returns subnormal numbers). The benefit of this function is that it returns a meaningful result for out-of-range situations, so it is possible to determine the cause of out-of-range.



If you want to handle out of range situations, you'll need to check errno for ERANGE. Note, that if a subnormal/zero number is a result, then maybe errno will be set to ERANGE, which you should ignore (you can check this out with fpclassify).



So the logic is something like this:



double r = strtod(string, &end);
// here, check for end to know about invalid strings

if (errno==ERANGE) { // out-of-range (overflow, underflow)
int c = fpclassify(r);
if (c!=FP_SUBNORMAL&&c!=FP_ZERO) { // let's filter out underflow cases
// "real" out of range handling here, just overflow
}
}





share|improve this answer





















    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',
    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%2f53375554%2fexplicit-specification-of-the-double-precision-representation-used-by-compiler%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








    up vote
    3
    down vote



    accepted










    Unfortunately, std::stod is badly designed, because it is not possible to determine what caused the std::out_of_range exception.



    I'd suggest you to use strtod instead. While is not specified in the standard what this function should do for subnormal numbers, it behaves well for subnormal numbers usually (it means that it returns subnormal numbers). The benefit of this function is that it returns a meaningful result for out-of-range situations, so it is possible to determine the cause of out-of-range.



    If you want to handle out of range situations, you'll need to check errno for ERANGE. Note, that if a subnormal/zero number is a result, then maybe errno will be set to ERANGE, which you should ignore (you can check this out with fpclassify).



    So the logic is something like this:



    double r = strtod(string, &end);
    // here, check for end to know about invalid strings

    if (errno==ERANGE) { // out-of-range (overflow, underflow)
    int c = fpclassify(r);
    if (c!=FP_SUBNORMAL&&c!=FP_ZERO) { // let's filter out underflow cases
    // "real" out of range handling here, just overflow
    }
    }





    share|improve this answer

























      up vote
      3
      down vote



      accepted










      Unfortunately, std::stod is badly designed, because it is not possible to determine what caused the std::out_of_range exception.



      I'd suggest you to use strtod instead. While is not specified in the standard what this function should do for subnormal numbers, it behaves well for subnormal numbers usually (it means that it returns subnormal numbers). The benefit of this function is that it returns a meaningful result for out-of-range situations, so it is possible to determine the cause of out-of-range.



      If you want to handle out of range situations, you'll need to check errno for ERANGE. Note, that if a subnormal/zero number is a result, then maybe errno will be set to ERANGE, which you should ignore (you can check this out with fpclassify).



      So the logic is something like this:



      double r = strtod(string, &end);
      // here, check for end to know about invalid strings

      if (errno==ERANGE) { // out-of-range (overflow, underflow)
      int c = fpclassify(r);
      if (c!=FP_SUBNORMAL&&c!=FP_ZERO) { // let's filter out underflow cases
      // "real" out of range handling here, just overflow
      }
      }





      share|improve this answer























        up vote
        3
        down vote



        accepted







        up vote
        3
        down vote



        accepted






        Unfortunately, std::stod is badly designed, because it is not possible to determine what caused the std::out_of_range exception.



        I'd suggest you to use strtod instead. While is not specified in the standard what this function should do for subnormal numbers, it behaves well for subnormal numbers usually (it means that it returns subnormal numbers). The benefit of this function is that it returns a meaningful result for out-of-range situations, so it is possible to determine the cause of out-of-range.



        If you want to handle out of range situations, you'll need to check errno for ERANGE. Note, that if a subnormal/zero number is a result, then maybe errno will be set to ERANGE, which you should ignore (you can check this out with fpclassify).



        So the logic is something like this:



        double r = strtod(string, &end);
        // here, check for end to know about invalid strings

        if (errno==ERANGE) { // out-of-range (overflow, underflow)
        int c = fpclassify(r);
        if (c!=FP_SUBNORMAL&&c!=FP_ZERO) { // let's filter out underflow cases
        // "real" out of range handling here, just overflow
        }
        }





        share|improve this answer












        Unfortunately, std::stod is badly designed, because it is not possible to determine what caused the std::out_of_range exception.



        I'd suggest you to use strtod instead. While is not specified in the standard what this function should do for subnormal numbers, it behaves well for subnormal numbers usually (it means that it returns subnormal numbers). The benefit of this function is that it returns a meaningful result for out-of-range situations, so it is possible to determine the cause of out-of-range.



        If you want to handle out of range situations, you'll need to check errno for ERANGE. Note, that if a subnormal/zero number is a result, then maybe errno will be set to ERANGE, which you should ignore (you can check this out with fpclassify).



        So the logic is something like this:



        double r = strtod(string, &end);
        // here, check for end to know about invalid strings

        if (errno==ERANGE) { // out-of-range (overflow, underflow)
        int c = fpclassify(r);
        if (c!=FP_SUBNORMAL&&c!=FP_ZERO) { // let's filter out underflow cases
        // "real" out of range handling here, just overflow
        }
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 19 at 18:01









        geza

        12.3k32774




        12.3k32774






























            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.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • 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%2f53375554%2fexplicit-specification-of-the-double-precision-representation-used-by-compiler%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







            Popular posts from this blog

            Costa Masnaga

            Fotorealismo

            Sidney Franklin