如何解决 numeric_limits::min() 定义不一致的问题?
numeric_limits 特征应该是获取各种类型信息的通用方法,能够执行类似的操作
template<typename T>
T min(const std::vector<T>& vect)
{
T val = std::numeric_limits<T>::min();
for(int i=0 ; i<vect.size() ; i++)
val = max(T, vect[i]);
return val;
}
问题是(至少使用 MS Visual Studio 2008) numeric_limits
有人知道这个设计背后的原理吗? 有没有更好(推荐?)的使用 numeric_limits 的方法? 在上面的特定函数中,我当然可以将 T 初始化为 vect[0],但这不是我正在寻找的答案。
另请参阅(浮点特定)讨论 此处
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可以使用 Boost 库。 Numeric Conversions 库提供了一个名为bounds 的类,可以一致使用。
请参阅此处的文档。
You can use Boost libraries. The library Numeric Conversions provides a class called bounds that can be used consistently.
See the documentation here.
这是一个旧线程,但有一个更新的答案:
C++11 向
std::numeric_limits
添加了lowest()
函数 (参见此处)因此您现在可以调用
std::numeric_limits::lowest()
来获取最低可表示的负值。This is an old thread, but there is an updated answer:
C++11 added a
lowest()
function tostd::numeric_limits
(See here)So you can now call
std::numeric_limits<double>::lowest()
to get the lowest representable negative value.min() 的行为并不那么奇怪,它返回
FLT_MIN
、DBL_MIN
或INT_MIN
(或它们各自的值),具体取决于您擅长的类型。 因此,您的问题应该是为什么FLT_MIN
和DBL_MIN
的定义与INT_MIN
不同。不幸的是,我不知道后一个问题的答案。
我怀疑它是出于实际目的而这样定义的。 对于整数,您通常关心上溢/下溢,其中最小值和最大值变得令人感兴趣。
对于浮点数,存在一种不同类型的下溢,因为计算可能会产生大于零但小于该浮点类型的最小可表示小数的值。 了解最小可表示浮点值可以让您解决该问题。 另请参阅有关次正常/非正常数字的维基百科文章。
The behaviour of min() isn't all that strange, it returns
FLT_MIN
,DBL_MIN
orINT_MIN
(or their respective values), depending on the type you specialize with. So your question should be whyFLT_MIN
andDBL_MIN
are defined differently fromINT_MIN
.Unfortunately, I don't know the answer to that latter question.
My suspicion is that it was defined that way for practical purposes. For integer numbers, you're usually concerned with overflow/underflow, where the minimum and maximum value become of interest.
For floating point numbers, there exists a different kind of underflow in that a calculation could result in a value that's larger than zero, but smaller than the smallest representable decimal for that floating point type. Knowing that smallest representable floating point value allows you to work around the issue. See also the Wikipedia article on subnormal/denormal numbers.
当然
,这并不能解释 numerics_limits::min() 的奇怪行为,这可能是由于整数有不同的最小/最大边界(min = -2^n,max = 2^n-1) 但不适用于双打。
A workaround would be
Of course, this doesn't explain the strange behaviour of numerics_limits::min() which could be a result of the fact that there are different min/max borders for integers (min = -2^n, max = 2^n-1) but not for doubles.
我不确定其理由,但这是预期的行为。 好吧,从某种意义上说,这就是 Josuttis(以及大概的标准)所描述的!
可以最好地判断该类型是否不是整数(
numeric_limits<>::is_integer
)并且有非规范化 (numeric_limits<>::has_denorm
)min()
将返回该类型的最小可表示值,否则它将返回最小值 -对于更一致的界面,请查看 Boost numeric/conversion 库,特别是
bounds
特征类。以下是一个片段:您还可以找到 boost::integer 库 很有用。它带来了一些 C99 的整数支持(例如
int_least16_t
) 到 C++,可以帮助您选择适合您特定需求的最佳尺寸类型。 举个例子:我经常发现,当我需要 boost::numeric/conversion 或 boost::integer 之一时,我需要它们两者。
I'm not sure of the rationale but it is expected behaviour. Well, in the sense that is how Josuttis (and, presumably the standard) describes it!
As best I can tell if the type is not an integer (
numeric_limits<>::is_integer
) and has denormalization (numeric_limits<>::has_denorm
)min()
will return the smallest representable value by that type. Otherwise it will return the smallest value - which may be negative.For a more consistent interface check out the Boost numeric/conversion library. Specifically the
bounds
traits class. Here's a snippet:You may also find the boost::integer library useful. It brings some of C99's integer support (like
int_least16_t
) to C++ and can help select the best sized type for you particular need. An example:I often find that when I need one of boost::numeric/conversion or boost::integer I need them both.
numeric_limits::min
返回最小负数,所有浮点数类型,当我尝试使用时返回最小正数孙CC& g++。我想这是因为“最小”和“最小”对于浮点数来说意味着不同的东西。 不过这有点奇怪。
Sun CC 和 g++ 都产生相同的结果:
numeric_limits<int>::min
returned the lowest negative number, all floating point number types, return the smallest positive number when I tried it with Sun CC & g++.I guess this is because 'smallest' and 'minimum' mean different things with floating point numbers. It is a bit odd though.
Both Sun CC and g++ produce the same result :
空向量最小值的定义是有争议的。 如果向量为空,则没有最小元素。
更喜欢使用 std::min_element 代替:
The definition of the smallest value for an empty vector can be argued. If the vector is empty then there is no smallest element.
Prefer to use std::min_element instead: