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

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

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

Ответ 1

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

Ответ 2

Вы можете использовать -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().

Ответ 3

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

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

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

Ответ 4

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

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

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

Ответ 5

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