如何将浮点数初始化为最大/最小值?

Fak*_*ken 94 c++ primitive-types

如何硬编码浮点数或双精度的绝对最大值或最小值?我想通过简单地迭代并捕获最大的数据来搜索数组的最大/最小值.

对于花车还有正负无穷大,我应该使用它们吗?如果是这样,我如何在我的代码中表示?

Yac*_*oby 145

您可以使用std::numeric_limits定义<limits>的类型来查找类型的最小值或最大值(只要该类型存在特殊化).您也可以使用它来检索无穷大(并-在前面设置负无穷大).

#include <limits>

//...

std::numeric_limits<float>::max();
std::numeric_limits<float>::min();
std::numeric_limits<float>::infinity();
Run Code Online (Sandbox Code Playgroud)

如评论中所述,min()返回可能的最低正值.换句话说,可以表示最接近0的正值.最低可能值是最大可能值的负值.

当然std::max_element还有min_element函数(定义中<algorithm>),它们可能是查找数组中最大或最小值的更好选择.

  • @Yacoby,您可能想澄清一下,numeric_limits <float> :: min()并不意味着最负值,它意味着最小的正值. (17认同)
  • @killogre:C++ 11添加了`numeric_limits <T> :: lowest()`,它返回类型可能的最低(负)值来解决这个问题. (12认同)
  • `std :: numeric_limits <float> :: min()`确实*不*给出可以表示的最小正值; 它给出了最小的*正常*单精度浮点数.零和此数字之间也有*次正常*数字.特别是,`std :: numeric_limits <float> :: min()`给出`1.17549e-38`,但最小的可表示的低于正常的浮点数是`nextafterf(0.0f,1.0f)== 1.4013e-45f`. (3认同)

MSN*_*MSN 40

您可以使用-FLT_MAX(或-DBL_MAX)表示最大幅度负数,FLT_MAX(或DBL_MAX)表示正数.这为您提供了可能的浮点(或双精度)值的范围.

你可能不想用FLT_MIN; 它对应于可用float表示的最小幅度正数,而不是浮点数表示的最负值.

FLT_MINFLT_MAX对应于std::numeric_limits<float>::min()std::numeric_limits<float>::max().

  • "[`FLT_MIN`]对应于可以用浮点数表示的最小幅度正数" - **这不是真的**.这是最小的*正常*数字.还有次正规数. (2认同)

Jer*_*fin 17

没有必要初始化到最小/最大可能找到数组中的最小/最大:

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];
}
Run Code Online (Sandbox Code Playgroud)

或者,如果你不止一次这样做:

#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;
}
Run Code Online (Sandbox Code Playgroud)

提供示例代码的缺点 - 我看到其他人已经提出了同样的想法.

请注意,虽然标准具有min_element和max_element,但使用这些将需要扫描两次数据,如果数组很大,则可能会出现问题.最近的标准通过添加a来解决这个问题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;
}
Run Code Online (Sandbox Code Playgroud)

请注意,这仍然使用第一个元素作为初始值,但我们仍然不需要任何"特殊情况"代码 - 因为它将回绕到最大可能值,任何非零值将比较为更小.结果将是最小的非零值,或者当且仅当向量不包含非零值时才为0.

  • 我初始化为最大分钟,因为有时我想要最小的非零值(例如,在无符号整数的情况下,我的数据往往有很多无趣的零)。对我来说,初始化它似乎是有意义的,而不是执行额外的检查以确保第一个元素不为零。 (2认同)
  • @Jerry:C++ 0x会添加minmax_element来解决你提到的问题.(但那么就不可能忽略零...) (2认同)

Bil*_*ill 5

要手动查找数组的最小值,您不需要知道float的最小值:

float myFloats[];
...
float minimum = myFloats[0];
for (int i = 0; i < myFloatsSize; ++i)
{
  if (myFloats[i] < minimum)
  {
    minimum = myFloats[i];
  }
}
Run Code Online (Sandbox Code Playgroud)

和最大值的类似代码.


Tho*_*thy 5

我可以建议您将“到目前为止的最大和最小”变量初始化为数组中的第一个数字,而不是无穷大吗?