Does a value x of type float exist for which x + 1 == x?
Sure.
#include <limits>
#include <iostream>
int main() {
float f = std::numeric_limits<float>::infinity();
std::cout << (f == f + 1) << std::endl;
}
As Deduplicator points out, if your float
is big enough (works for me with float f = 1e20;
), it'll also work because the added 1
would be outside of the float
's accuracy.
Try it online
This code compiles without error:
#include <limits>
int main()
{
static_assert(std::numeric_limits<float>::infinity() == std::numeric_limits<float>::infinity() + 1.0f, "error");
static_assert(std::numeric_limits<double>::infinity() == std::numeric_limits<double>::infinity() + 1.0, "error");
return 0;
}
online version
You don't need to even use infinity. If the number is big enough, rounding errors become big enough so adding one to the number doesn't change it at all. E.g.
static_assert(100000000000000000000000.f == 100000000000000000000000.f + 1.0, "error");
The specific number of 0
you have to put here may be implementation defined, though.
Always keep rounding in mind when you write programs that use floating point numbers.
#include <iostream>
int main()
{
float val = 1e5;
while (val != val + 1)
val++;
std::cout << val << "\n";
return 1;
}
Prints 1.67772e+07
for clang.
There exists a value x of the type float for that holds: x + 1 == x... which is true. Why tho?
The reason for that lies in how floating point numbers work. Basically a 32bit float has 24 bits for the mantissa (the base digits) and 8 bits for the exponent. At some point +1 just doesn't cause a change in the binary representation because the exponent is too high.