Largest number <x?

In C ++, suppose I have a number x type T , which can be integer or floating point. I want to find the largest number y type T for which y < x . The solution should be a template for transparent work with integers and floating point numbers. You can ignore the edge, where x is the smallest number that can be represented in T

POSSIBLE USE OF CASE: This question has been marked as too localized, so I would like to provide an example of use, which, I think, is more general. Please note that I am not the original author of 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 mimics a lower bound that can be open or closed. Of course, in real (punctured) life we โ€‹โ€‹cannot do this. A stream is impossible (or at least rather complicated) to compute S of all real numbers.

enter image description here

However, when S is a set of floating point numbers, this is a very valid principle, since we are dealing with a substantially countable set; and then there is no such thing as an open or closed border. That is,> = can be defined in terms of> as done in the lower_bound class.

For simplicity, I used +0.1 to simulate an open lower bound. Of course, 0.1 is a raw value since there can be z values โ€‹โ€‹such that the value <z <= value + 0.1 or the value + 0.1 == value in the floating point representation. Therefore, @ brett-hale answer is very useful :)

You might think of 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, since sizeof (Lower_bound) is larger, and operator () requires the execution of a more complex operator. The first implementation is really effective and can be implemented simply as a double, not a structure. Technically, the only reason to use the second implementation is because you assume double is continuous, while it is not, and I think it will not be in the foreseeable future.

I hope that I have created and explained a valid precedent, and that I did not offend the author.

+6
source share
1 answer

If you have C ++ 11, you can use std::nextafter in <cmath> :

 if (std::is_integral<T>::value) return (x - 1); else return std::nextafter(x, - std::numeric_limits<T>::infinity()); 
+11
source

All Articles