4

给定一个定义为的变量

T x;

哪里T是通用算术类型(即,这样std::is_arithmetic<T>::value),是否有一个简单的表达式(例如来自 的东西),std::numeric_limits其计算结果为可表示的最低值> ?yTyx

(即一种广义增量..)

4

3 回答 3

5

您可以使用std::nextafter.

请注意,我在这里使用std::numeric_limits<Floating>::max(),如果您想要对无穷大有意义的行为,您可能需要修改代码。

#include <iostream>
#include <limits>
#include <cmath>
#include <type_traits>
#include <iomanip>

template <typename Floating,
    std::enable_if_t<std::is_arithmetic_v<Floating> && !std::is_integral_v<Floating>, bool> = false>
Floating generic_next_val(Floating val) {
    return std::nextafter(val, std::numeric_limits<Floating>::max());
}

template <typename Integral,
    std::enable_if_t<std::is_arithmetic_v<Integral> && std::is_integral_v<Integral>, int> = 0>
Integral generic_next_val(Integral val) {
    return static_cast<Integral>(val + static_cast<Integral>(1));
}

int main() {
    int a = 1;
    float f = 0.0f;
    std::cout << std::setprecision(20) << generic_next_val(f) << " " << generic_next_val(a) << std::endl;
    return 0;
}
于 2019-11-20T04:53:23.587 回答
1

标题<cmath>std::nexttoward()执行此操作。它接受浮点、双精度、长双精度或整数类型,并返回其第二个参数方向的下一个值。

所以,给定这样的代码:

T my_val = some_input; // float, double, int, etc.
T next = std::nexttoward(my_val, std::numeric_limits<T>::max());`

如果my_val是 1.0f,next将是 1 之后的下一个最大浮点数;如果my_val是整数 2,你会得到 3,等等。

(请注意,这里有很多关于数字溢出的详细说明,上面链接的 CppReference 页面对此进行了讨论。它的长短是不要传入std::numeric_limits<T>::max()第一个参数。)

于 2019-11-20T04:24:36.053 回答
0
#include <type_traits>
#include <limits>
#include <iostream>

/*
NOTE: Untested code for 'proof' of concept only.

This will cover all the is_integral<T> except bool.

This should probably be a set of free functions rather than a class
but just to check out the idea. Class should have constraints but as
the final implementation should probably be free functions they are
omitted.
*/
template<typename T>
class GLB{
public:
    using limits = std::numeric_limits<T>;

    static T get(const T& value){
       return value == limits::max() ? limits::max() : value + static_cast<T>(1);
    }
};

int main(int, char**){

    std::cout << GLB<int>::get(42) << '\n';
    std::cout << GLB<unsigned>::get(42) << '\n';
    std::cout << GLB<wchar_t>::get(42) << '\n';
    return 0;
}

/*
 That was the easy bit now what about the floating point numbers.
*/

虽然玩弄这个 scur3 指出 cmath 可以解决浮点值。所以需要一些打字和一些测试。

于 2019-11-20T04:50:23.043 回答