In C++, let's say I have a number x
of type T
which can be an integer or floating point type. I want to find the largest number y
of type T
for which y < x
holds. The solution needs to be templated to work transparently with both integers and floating point numbers. You may ignore the edge case where x
is already the smallest number that can be represented in a T
.
POSSIBLE USE CASE: This question was marked as too localized, hence I would like to provide a use case which I think is more general. Note that I'm not the original author of the OP.
Consider this structure:
struct lower_bound {
lower_bound(double value, bool open) : value(open? value+0.1 : value) {}
double value;
bool operator()(double x) { return x >= value; }
};
This class simulates an lower bound which can either be open or closed. Of course, in real (pun intended) life we can not do this. The flowing is impossible (or at least quite tricky) to calculate for S being all real numbers.
However, when S is the set of floating point numbers, this is a very valid principle, since we are dealing with essentially a countable set; and then there is no such thing as an open or closed bound. That is, >= can be defined in terms of > like done in the lower_bound class.
For code simplicity I used +0.1 to simulate an open lower bound. Of course, 0.1 is a crude value as there may be values z such that value < z <= value+0.1 or value+0.1 == value in a floating point representation. Hence @brett-hale answer is very useful :)
You may think about another simpler solution:
struct lower_bound {
lower_bound(double value, bool open) : open(open), value(value) {}
bool open;
double value;
bool operator()(double x) { return (open ? x > value : x>=value); }
};
However, this is less efficient as the sizeof(Lower_bound) is larger, and operator() needs to execute a more complicated statement. The first implementation is really efficient, and can also be implemented simply as a double, instead of a structure. Technically, the only reason to use the second implementation is because you assume a double is continuous, whereas it is not and I guess it will not be anywhere in the foreseeable future.
I hope I have created and explained a valid use case, and that I have not offended the original author.
There is no biggest, last number … except infinity. Except infinity isn't a number. But some infinities are literally bigger than others.
The largest number that has a commonly-known specific name is a "googleplex", which is a 1 followed by a googol zeros, where a "googol" is. (a 1 followed by 100 zeros).
Immortalised in common usage by the internet giant, a googol is the number 10100 – 10, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000.
If you have C++11, you could use std::nextafter
in <cmath>
:
if (std::is_integral<T>::value)
return (x - 1);
else
return std::nextafter(x, - std::numeric_limits<T>::infinity());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With