1. Why does the example of comparing the ind variable with itself give a negative result?
  2. To check for infinity, is it possible to use this construct if(ind != ind) ?
  3. What is this value in memory, is it stored as a number or how, because it is impossible to compare it?
  4. Is the variable ind greater than 5.4, less than 5.4, or equal to 5.4?

     double zero = 0.0; double pinf = 1 / zero; double minf = -pinf; double ind = pinf - pinf; std::cout << "\nind=" << ind; //-1.#IND if(ind == std::numeric_limits<double>::infinity()) { std::cout << "\n\nинфинити:" << ind; } if(ind == -std::numeric_limits<double>::infinity()) { std::cout << "\n\nинфинити2:" << ind; } if(ind != ind) { std::cout << "\n\nинфинити3:" << ind; } 
  • > What is this value in memory? The nearest Google, IEEE 754> Infinity and all Infinite values ​​are denoted. The sign bit distinguishes between negative infinity and positive infinity. It allows you to use it. Operations with infinite values ​​are well defined in IEEE floating point. - etki
  • one
    Sorry you can not put a minus for the comments. Translate to Russian, I'm not in English. Forum I ask a question. I want to read the comments in Russian, and not a link to the standard. - manking
  • 2
    @manking is awful. It seems to have brought the answer, but no - I didn’t try enough, nevertheless it’s a minus. What does double / float consist of? Out of sign (1 bit), exponent (11/8 bit) and mantissa (52/23 bit). For infinity values, states are reserved in which all bits of the exponent are set to 1, and all bits of the mantissa are set to zero. wiki for one hundred percent ru.wikipedia.org/wiki/… - etki
  • @Etki That's better. How to check for infinity using language constructs? Is it possible or not? - manking
  • 3
    @manking, without the ability to at least read and understand English in the field of IT you do not shine. - avp

1 answer 1

According to the C ++ language standard, the way to represent floating-point types is determined by implementation. You can use the static member is_iec559 template class std::numeric_limits to check the compliance of some type with the IEEE 754-2008 standard:

 std::numeric_limits<double>::is_iec559 

It is true if the type meets the requirements of IEEE 754-2008. Further, the answer assumes that the double type satisfies the requirements of this standard.

So, if you divide 1.0 by 0.0 , you get positive infinity ( Infinity ). One of the possible ways that an implementation using std::cout can display infinity is 1.#INF .

The difference of two infinities with the same sign is NaN . One of the possible ways that an implementation through std::cout can display NaN is -1.#IND .

  1. The variable ind in your example is equal to NaN . NaN not equal to anything, including itself. That is why the expression ind != ind is true .
  2. The if(ind != ind) construct can be used to test for NaN , but not for infinity. Starting with C ++ 11, the <cmath> header file contains the std::isnan for testing on NaN and the std::isinf for checking for infinity.
  3. Both NaN 's and infinity are stored in memory as well as all the other floating point numbers: the sign bit, exponent bits and mantissa bits. If all bits of the exponent are set to 1 , and all bits of the mantissa are set to 0 , then this is infinity (positive or negative, depending on the sign bit). If all bits of the exponent are set to 1 , and among the bits of the mantissa there is at least one non-zero, then this is NaN .
  4. Operators < , <= , == , >= , > return false if at least one of the operands is NaN . Therefore, all expressions ind < 5.4 , ind == 5.4 , ind > 5.4 return false . Infinities are compared in the usual way: −Infinity < every_finite_number < +Infinity .

The C ++ language standard is not particularly demanding on floating point types. Many aspects of the behavior of these types are determined by implementation. For example, the IEEE 754-2008 standard permits that if one of the binary operands is > NaN , then an exception is generated.

When working with floating-point numbers, it is worth remembering about possible aggressive optimizations that the compiler can use. For example, in Visual Studio, when using the / fp: fast option, the compiler can easily pinf - pinf to replace with zero (which if pinf is infinite or NaN - not true), and ind != ind to false to replace (that if ind is equal to NaN - not true).