4

I have a peculiar usecase where I have some edges w/ double weights set initially to std::numeric_limits<double>::infinity(). These weights will be set to something else later on in program execution.

Now that we have the context, here is the main issue. I need to compare these edge weights to the square of some weight that I compute, and to account for the squaring of my computed weight, I will also have to square the edge weights. Of course, this will result in an initial multiplying of infinity by infinity. I am wondering if multiplying a double set to std::numeric_limits<double>::infinity() by itself is defined behavior. Can I expect it to remain unchanged?

I could not find any documentation even on cppreference.

Alex Ni
  • 75
  • 6
  • At the first glance, I wondered about your concerns. Out of curiosity, I googled a bit. Now, I came to the conclusion your concerns are very reasonable. FYI: [re the results of floating point calculations involving infinity and NaN specified in IEEE 754?](https://stackoverflow.com/q/48483738/7478597), [Are floating point operations resulting in infinity undefined behavior for IEC 559/IEEE 754 floating-point types](https://stackoverflow.com/q/56097944/7478597). – Scheff's Cat Apr 19 '22 at 13:33
  • This one is more promising: [Is the inverse of std::numeric_limits::infinity() zero?](https://stackoverflow.com/q/52015831/7478597) which directed me to [Infinity and NaN](https://www.gnu.org/software/libc/manual/html_node/Infinity-and-NaN.html): _The basic operations and math functions all accept infinity and NaN and produce sensible output._ However, it's about the GNU C lib. and I haven't an idea how it's related to the C++ standard. – Scheff's Cat Apr 19 '22 at 13:40
  • Does this depend on the underlying representation? In case it does, are you asking for IEEE 754? – François Andrieux Apr 19 '22 at 13:46
  • Is it actually necessary to use infinity here? Would the square root of `std::numeric_limitsmax()` (perhaps with a little bit knocked off for safety) do you? – Paul Sanders Apr 19 '22 at 14:19

1 Answers1

5

Restricting this answer to IEEE754, using +/-Inf as some sort of starting value brings a fair bit of trouble.

Under IEEE754,

  1. Inf * 0.0 = NaN
  2. -Inf * 0.0 = Inf * -0.0 = -NaN
  3. Inf * Inf = -Inf * -Inf = Inf
  4. -Inf * Inf = -Inf

Inf multiplied by any positive floating point value (including a subnormal value) is Inf, and similarly for -Inf.

In other words, you need to treat +0.0 and -0.0 as special cases when multiplying, and is one of those rare cases where a signed negative zero produces a different result. Use std::isnan to test, if you cannot adopt some other scheme.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483