Prevent "Float-point invalid operation" exception? RRS feed

  • Question

  • Hi,


    I am using Visual C++ to load binary data into float, like this:


    double dValue

    memcpy(&dValue, lpData, sizeof(dValue));


    For normal cases, this will work properly. However, for some rare cases, when binary data are corrupt, the dValue will be invalid and any further operations on it will cause “Float-point invalid operation” exception.


    I check the dValue in debugger and it displays as “-1.#QNAN00000000000”.


    To prevent the exception, I need to verify the dValue after it is loaded from the binary data. I try to use:


    if (_finite(dValue))


    … do some tasks…



    But still the invalid dValue will cause _finite function to raise an “Float-point invalid operation” exception. Although _finite(dValue) will return 0 properly, the exception will be allocated in memory. Even if I deallocate it. Too many allocate/deallocate will still exhaust the system resources.


    Therefore, is there a way to detect the validness of a double value without raising any exceptions?



    • Edited by chcw Wednesday, February 3, 2016 4:21 AM
    Wednesday, February 3, 2016 3:12 AM


All replies

  • Can you use isnan()?

    isnan Function

    Or isnormal()?

    isnormal Function

    - Wayne

    Wednesday, February 3, 2016 4:41 AM
  • Wednesday, February 3, 2016 4:43 AM
  • There should be isfinite isinf, isnan, isnormal in math.h
    but I haven't checked or tried them. See:

    C99 library support in Visual Studio 2013

    Note that these *may* not be available via <cmath>, only math.h - although again I haven't
    checked or tried them.

    Also see:

    Checking if a double (or float) is nan in C++

    - Wayne
    Wednesday, February 3, 2016 4:58 AM
  • Hi,

    Exceptions can cause a memory leak? About issue you can refer to the book(Professional C++ Nicholas A.Solter Scott J.Kleper). In this book the author used smart pointers to prevents memory leaks with exception handling. Smart pointer objects are allocated on the stack. You never have to remember to delete the underlying dump pointer.

    The books linkhttps://books.google.co.jp/books?id=YkwA3DeET8UC&pg=PA423&lpg=PA423&dq=exception+can+lead+memory+leak++%EF%BC%9F&source=bl&ots=yREUEDkVWE&sig=PmUZ8dauDv65Q31THIbI3XCbvs0&hl=en&sa=X&ved=0ahUKEwi4w87d9drKAhViMKYKHTDhCkcQ6AEIPzAG#v=onepage&q=exception%20can%20lead%20memory%20leak%20%20%EF%BC%9F&f=false

    Best Regards,


    This response contains a reference to a third party World Wide Web site. Microsoft is providing this information as a convenience to you. Microsoft does not control these sites and has not tested any software or information found on these sites; therefore, Microsoft cannot make any representations regarding the quality, safety, or suitability of any software or information found there. There are inherent dangers in the use of any software found on the Internet, and Microsoft cautions you to make sure that you completely understand the risk before retrieving any software from the Internet. 

    • Proposed as answer by Hart Wang Monday, February 15, 2016 8:48 AM
    • Marked as answer by May Wang - MSFT Wednesday, February 17, 2016 8:11 AM
    Wednesday, February 3, 2016 6:25 AM
  • A long, long time ago I had to do conversions of DEC floating point numbers to IEEE floating point numbers and this is a note I made in that code

     // The format of a IEEE real*4 is as follows:
     // (1) The mantissa occupies 23 bits. It is a 24 bit number
     // with the redundant MSB not stored. The mantissa is
     // stored in bit positions 0 -> 22 (16 -> 22 are in the
     // high order word) with the MSB in position 22. The
     // binary radix is to the right of the hidden bit so that
     // 1.xxxxx... is the representation of the mantissa.
     // (2) The exponent occupies 8 bits 23 -> 30.
     // It is stored in binary excess 127 notation such that
     // exponents from -127 to 127 are represented by the binary
     // equivalents of 0 through 254. All bits set in the
     // exponent represents an invalid real number and is not
     // allowed (i.e. 254 is the largest allowable exponent).
     // (3) The sign bit is in position 31.
     // (4) This format allows for positive numbers in the range of
     // SeeeEeeeEmmmMmmmMmmmMmmmMmmmMmmm
     // 00000000000000000000000000000001 = 0.140130E-44 ->
     // 01111111011111111111111111111111 = 0.340282E+39
     // to be represented.
     // (5) When the sign bit, mantissa, and exponent are expressed as
     // integers, the real number can be reconstructed through use
     // of the equation
     // -1^s  * (1 + m / 2^23) * 2^(e-127)

    So if you were working with float values you could just 'or' your number with 0x7F800000 and if the result is 0x7F800000 then your number is NAN.

    I didn't deal with IEEE*8 variables then so I did not include the info in my note.  However it is the same general format with 64 bits instead of 32.  If I remember right the exponent in an IEEE*8 floating point number occupies 11 bits so the exponent bits only would be 0x7FF.  It shouldn't be hard to verify that.  So if you can't find a library function to do what you want writing your own should not be too tough.

    Wednesday, February 3, 2016 8:49 AM
  • May -

    Why on earth did you mark Hart's reply as the answer? It doesn't even address
    the problem raised by the OP. Did you not understand what the problem is any
    better than Hart did?

    The OP's question was:

    "is there a way to detect the validness of a double value without raising
    any exceptions?"

    Hart's reference to a book which describes the use of smart pointers with
    exception handling does not answer the question asked: how to detect if a
    double is valid.

    I don't think this is the first time you have given Hart questionable credit
    for answering a thread. Do it too often and those who have been answerers here
    for years may choose to stop participating. The fact that both you and Hart
    are Microsoft Contingent Staff doesn't mean you should give credit where it
    isn't due.

    - Wayne

    Wednesday, February 17, 2016 8:36 AM