代码之家  ›  专栏  ›  技术社区  ›  Museful

大于给定值的最小可表达值

  •  3
  • Museful  · 技术社区  · 5 年前

    给定一个定义为

    T x;

    哪里 T 是泛型算术类型(即 std::is_arithmetic<T>::value ),是否有一个简单的表达式(例如 std::numeric_limits y 表达于 T 就这样 是的 x

    (即一种广义增量)

    1 回复  |  直到 5 年前
        1
  •  5
  •   ph3rin    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;
    }
    
        2
  •  1
  •   s3cur3 Aleksei Matiushkin    5 年前

    这个 <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之后的下一个最大的浮动;如果 我的价值

    (请注意,这里有很多关于数字溢出的细节,上面链接的CppReference页面讨论了这些细节。长短不一是不及格 std::numeric_limits<T>::max() 第一个参数)

        3
  •  0
  •   systemcpro    5 年前
    #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.
    */