Answers:
您可以使用std::numeric_limits
其中定义的值<limits>
来查找类型的最小值或最大值(只要该类型存在特殊化)。您还可以使用它来检索无穷大(并-
在前面放置负无穷大)。
#include <limits>
//...
std::numeric_limits<float>::max();
std::numeric_limits<float>::min();
std::numeric_limits<float>::infinity();
如注释中所述,min()
返回可能的最低正值。换句话说,可以表示最接近0的正值。最低可能值是最大可能值的负数。
当然,std::max_element
还有和min_element函数(在中定义<algorithm>
)可能是查找数组中最大值或最小值的更好选择。
numeric_limits<T>::lowest()
,它返回用于解决该问题的类型的最低(负)值。
std::numeric_limits<float>::min()
并没有得到能够表示的最小正值; 它给出最小的常规单精度浮点数。在零和该数字之间也存在非正规数。特别是,std::numeric_limits<float>::min()
给出1.17549e-38
最小的可表示的次正规浮点为nextafterf(0.0f, 1.0f) == 1.4013e-45f
。
您可以将-FLT_MAX
(或-DBL_MAX
)表示为最大负数,将FLT_MAX
(或DBL_MAX
)表示为正数。这为您提供了可能的浮点(或双精度)值范围。
您可能不想使用FLT_MIN
; 它对应于可以用浮点数表示的最小量级正数,而不是可以用浮点数表示的最大负数。
FLT_MIN
并且FLT_MAX
对应于std::numeric_limits<float>::min()
和std::numeric_limits<float>::max()
。
FLT_MIN
]对应可以用浮点数表示的最小正数”- 这是不正确的。这是最小的标准数。也有不正常的数字。
FLT_TRUE_MIN
实际最小的浮动,对应于std::numeric_limits<float>::denorm_min()
真正没有必要初始化为最小/最大来找到数组中的最小/最大:
double largest = smallest = array[0];
for (int i=1; i<array_size; i++) {
if (array[i] < smallest)
smallest = array[i];
if (array[i] > largest0
largest= array[i];
}
或者,如果您不止一次这样做:
#include <utility>
template <class iter>
std::pair<typename iter::value_type, typename iter::value_type> find_extrema(iter begin, iter end) {
std::pair<typename iter::value_type, typename iter::value_type> ret;
ret.first = ret.second = *begin;
while (++begin != end) {
if (*begin < ret.first)
ret.first = *begin;
if (*begin > ret.second)
ret.second = *begin;
}
return ret;
}
提供示例代码的缺点-我看到其他人已经提出了相同的想法。
请注意,尽管标准具有min_element和max_element,但使用它们将需要对数据进行两次扫描,如果数组很大,则可能会出现问题。最近的标准通过添加来解决此问题std::minmax_element
,该功能与find_extrema
上面的功能相同(在一次遍历中找到集合中的最小和最大元素)。
编辑:解决在无符号数组中查找最小的非零值的问题:观察到无符号值达到极限时会“环绕”。为了找到最小的非零值,我们可以从每个值中减去一个进行比较。任何零值都将“包装”为该类型的最大可能值,但其他值之间的关系将保留。完成后,我们显然会将一加到找到的值上。
unsigned int min_nonzero(std::vector<unsigned int> const &values) {
if (vector.size() == 0)
return 0;
unsigned int temp = values[0]-1;
for (int i=1; i<values.size(); i++)
if (values[i]-1 < temp)
temp = values[i]-1;
return temp+1;
}
请注意,这仍然使用第一个元素作为初始值,但是我们仍然不需要任何“特殊情况”代码-因为它将环绕到最大可能值,所以任何非零值都将比较小。结果将是最小的非零值,或者仅当向量不包含非零值时才为0。
std::min_element
:bool less_ignoring_zero(unsigned a, unsigned b) { if (a == 0) return false; if (b == 0) return true; return a < b; }
我可以建议您将“到目前为止的最大和最小”变量初始化为不是无穷大,而是初始化为数组中的第一个数字吗?