确定一个数字(在我的情况下,它是由if(pow (2,128)>std::numeric_limits<float>::max())
计算的2的幂的值)是否在一个变量类型可以采用的值范围内的正确方法是什么?我这样做:true
,但这被评估为v.GetType()
,尽管预计浮动的最大值是2 ^ 128或更多。有没有更好的方法来进行这种比较?
答案 0 :(得分:2)
您可以取变量类型的最大限制的基数2对数,并将其与n
进行比较。例如:if(n > std::log2(std::numeric_limits<float>::max())
。你可能不希望n
完全符合限制,因为我认为像浮点错误之类的东西可能会导致一些问题,这就是为什么你的例子不起作用,即使限制正好是2 ^ 128。
答案 1 :(得分:1)
对于这些类型的限制检查,您可以移动这些术语以保持在类型的限制范围内。
在这种情况下,pow(2,n) == exp(ln(2)*n)
在数学上,因此,重新排列术语,您可以使用n > ln(maxval)/ln(2)
答案 2 :(得分:-2)
首先,您能回答pow(2, 128)
的结果吗?
真正的问题是这个表达的类型是什么?
第二个问题是你知道浮点数是如何工作的吗?
看看这段代码,给你一个提示:
#include <cmath>
#include <iostream>
#include <limits>
template<class T>
void printInfo(const std::string& desc, T x)
{
std::cout << desc << ' ' << typeid(x).name() << ' ' << x << std::endl;
}
int main()
{
printInfo("A", std::pow(2, 128));
printInfo("B", std::pow(2.0f, 128));
printInfo("A", std::pow(2, 128.0f));
auto c = std::pow(2.0f, 128.0f);
printInfo("C", c);
std::cout << (c > std::numeric_limits<float>::max()) << std::endl;
std::cout << (c == std::numeric_limits<float>::infinity()) << std::endl;
return 0;
}
https://wandbox.org/permlink/bHdKqToDKdC0hSvW
我建议审核numeric_limits的文档。 并分析此代码:
#include <cmath>
#include <iostream>
#include <limits>
template<class T>
void print2exp()
{
std::cout << typeid(T).name() << '\n';
std::cout << "Radix = " << std::numeric_limits<T>::radix << '\n';
auto maxExp = std::numeric_limits<T>::max_exponent;
std::cout << "Max exp = " << maxExp << '\n';
std::cout << "2^maxExp = " << std::pow(static_cast<T>(2), static_cast<T>(maxExp)) << '\n';
std::cout << "2^(maxExp - 1) = " << std::pow(static_cast<T>(2), static_cast<T>(maxExp - 1)) << '\n';
}
int main()
{
print2exp<float>();
print2exp<double>();
print2exp<long double>();
return 0;
}
https://wandbox.org/permlink/J0hACKUKvKlV8lYK
对此的正确方法是(假设基数为2):
if (x < std::numeric_limits<T>::max_exponent) {
return std::pow(static_cast<T>(2), static_cast<T>(x));
} else {
throw invalid_argument("x is to big to be use as 2^x");
}