как инициализировать float до его значения max/min?

Как мне жестко кодировать абсолютное максимальное или минимальное значение для float или double? Я хочу найти max / min массива, просто повторяя и ловя самый большой.

есть также положительная и отрицательная бесконечность для поплавков, должен ли я использовать их вместо этого? Если да, то как обозначить это в моем коде?

5 ответов


можно использовать 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>), который может быть лучшим выбором для поиска наибольшего или наименьшего значения в массиве.


можно использовать -FLT_MAX (или -DBL_MAX) для максимальной величины отрицательного числа и FLT_MAX (или DBL_MAX) для положительных. Это дает вам диапазон возможных значений float (или double).

вы, вероятно, не хотите использовать FLT_MIN; он соответствует наименьшему положительному числу величины, которое может быть представлено с помощью поплавка, а не самому отрицательному значению, которое можно представить с помощью поплавка.

FLT_MIN и FLT_MAX соответствуют std::numeric_limits<float>::min() и std::numeric_limits<float>::max().


нет реальной необходимости инициализировать наименьшее / наибольшее возможное, чтобы найти наименьшее / наибольшее в массиве:

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 выше (найдите как минимальные, так и максимальные элементы в коллекции за один проход).

Edit: решение проблемы поиска наименьшего ненулевого значения в массиве без знака: обратите внимание, что значения без знака "обертываются", когда они достигают экстремума. Чтобы найти наименьшее ненулевое значение, мы можем вычесть по одному из каждого Для сравнения. Любые нулевые значения будут "обернуты" к максимально возможное значение для типа, но отношения между другими значениями будут сохранены. После того, как мы закончим, мы, очевидно, добавим один к ценности, которую мы нашли.

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, если и только если вектор не содержал ненулевых значений.


чтобы вручную найти минимум массива, вам не нужно знать минимальное значение float:

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

и аналогичный код для максимального значения.


могу ли я предложить вам инициализировать переменные" max и min до сих пор " не до бесконечности, а до первого числа в массиве?