user81993
user81993

Reputation: 6613

Is maximum float + x defined behavior?

I did a quick test using the following:

float x = std::numeric_limits<float>::max();
x += 0.1;

that resulted in x == std::numeric_limits::max() so it didn't get any bigger than the limit.

Is this guaranteed behavior across compilers and platforms though? What about HLSL?

Upvotes: 2

Views: 243

Answers (2)

AlexD
AlexD

Reputation: 32576

Is this guaranteed behavior across compilers and platforms though?

No, the behavior is undefined. The standard says (emphasis mine):

5 Expressions
....
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined. [ Note: most existing implementations of C++ ignore integer overflows. Treatment of division by zero, forming a remainder using a zero divisor, and all floating point exceptions vary among machines, and is usually adjustable by a library function. —end note ]

As @user2079303 mentioned, in practice we can be less restricted:

it is not undefined if std::numeric_limits<float>::has_infinity. Which is often true. In that case, the result is merely unspecified.

Upvotes: 3

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153820

The value of std::numeric_limits<T>::max() is defined to be the maximum finite value representable by type T (see 18.3.2.4 [numeric.limits.members] paragraph 4). Thus, the question actually becomes multiple subquestions:

  1. Is it possible to create a value bigger than std::numeric_limits<T>::max(), i.e., is there an infinity?
  2. If so, which value needs to be added to std::numeric_limits<T>::max() to get the infinity?
  3. If not, is the behavior defined?

C++ does not specify the floating point format and different formats may disagree on what the result is. In particular, I don't think floating point formats need to define a value for infinity. For example, IBM Floating Points do not have an infinity. On the other hand the IEEE 754 does have an infinity representation.

Since overflow of arithmetic types may be undefined behavior (see 5 [expr] paragraph 4) and I don't see any exclusion for floating point types. Thus, the behavior would be undefined behavior if there is no infinity. At least, it can be tested whether a type does have an infinity (see 18.3.2.3 [numeric.limits] paragraph 35) in which case the operation can't overflow.

If there is an infinity I think adding any value to std::numeric_limits<T>::max() would get you infinity. However, determining whether that is, indeed, the case would require to dig through the respective floating point specification. I could imagine that IEEE 754 might ignore additions if the value is too small to be relevant as is the case for adding 0.1 to std::numeric_limits<T>::max(). I could also imagine that it decides that it always overflows to infinity.

Upvotes: 1

Related Questions