如何硬编码浮点数或双精度数的绝对最大值或最小值?我想通过简单地遍历并捕获最大值来搜索出数组的max/min。
浮点数也有正无穷大和负无穷大,我应该用它们来代替吗?如果是这样,我该如何在我的代码中表示呢?
发布于 2010-04-21 16:11:17
您可以使用<limits>
中定义的std::numeric_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>
中定义)可能是在数组中查找最大或最小值的更好选择。
发布于 2010-04-21 16:34:26
可以使用-FLT_MAX
(或-DBL_MAX
)表示最大幅值负数,使用FLT_MAX
(或DBL_MAX
)表示正值。这为您提供了可能的浮点值(或双精度值)的范围。
您可能不想使用FLT_MIN
;它对应于可以用浮点数表示的最小幅度正数,而不是可以用浮点数表示的最负的值。
FLT_MIN
和FLT_MAX
对应于std::numeric_limits<float>::min()
和std::numeric_limits<float>::max()
。
发布于 2010-04-21 16:25:04
实际上不需要初始化到最小/最大来找到数组中的最小/最大:
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。
https://stackoverflow.com/questions/2684603
复制