Существует ли стандартный и / или переносимый способ представления наименьшего отрицательного значения (например, использование отрицательной бесконечности) в программе на C (++)?
DBL_MIN в float.h - это наименьшее положительное число.
Существует ли стандартный и / или переносимый способ представления наименьшего отрицательного значения (например, использование отрицательной бесконечности) в программе на C (++)?
DBL_MIN в float.h - это наименьшее положительное число.
Ответы:
-DBL_MAX
в ANSI C , который определен в float.h.
-DBL_MAX
чтобы он был точно представлен, поэтому, если оборудование FP не способно на это, реализация просто должна обойти это. См. Модель с плавающей запятой в 5.2.4.2.2 Характеристики типов с плавающей запятой <float.h> p2 в C99 (с тех пор, возможно, были перемещены в другое место).
DBL_MAX
точно (1 - b ^ −p) b ^ e_max, что точно представимо, наиболее отрицательное конечное значение точно - (1 - b ^ −p) b ^ e_max, и поскольку это точно -DBL_MAX
, отрицание также DBL_MAX
не может привести к ошибкам округления.
Числа с плавающей запятой (IEEE 754) симметричны, поэтому, если вы можете представить наибольшее значение ( DBL_MAX
илиnumeric_limits<double>::max()
), просто добавьте знак минус.
А потом крутой способ:
double f;
(*((long long*)&f))= ~(1LL<<52);
В C используйте
#include <float.h>
const double lowest_double = -DBL_MAX;
В C ++ до 11 используйте
#include <limits>
const double lowest_double = -std::numeric_limits<double>::max();
В C ++ 11 и новее используйте
#include <limits>
constexpr double lowest_double = std::numeric_limits<double>::lowest();
min()
функция не была доступна до C ++ 11? Или это другое значение, чем -max()
? en.cppreference.com/w/cpp/types/numeric_limits
min
дает вам наименьшее положительное значение по величине и lowest
наибольшее отрицательное значение по величине. Да это ужасно. Добро пожаловать в блестящий мир стандартной библиотеки C ++ :-P
.
float.h
. limits.h
для целых чисел
Попробуй это:
-1 * numeric_limits<double>::max()
Справка: numeric_limits
Этот класс специализирован для каждого из основных типов, его члены возвращают или устанавливают различные значения, которые определяют свойства, которые тип имеет на конкретной платформе, на которой он компилируется.
-numeric_limits<double>::max()
?
-1 * ...
чтобы сделать его немного понятнее.
Вы ищете актуальную бесконечность или минимальное конечное значение? Если первое, используйте
-numeric_limits<double>::infinity()
который работает только если
numeric_limits<double>::has_infinity
В противном случае вы должны использовать
numeric_limits<double>::lowest()
который был введен в C ++ 11.
Если lowest()
недоступен, вы можете вернуться к
-numeric_limits<double>::max()
которые могут отличаться от них lowest()
в принципе, но обычно не работают.
-numeric_limits<double>::max()
даже если он работает на практике, он не является полностью переносимым в теории.
Начиная с C ++ 11 вы можете использовать numeric_limits<double>::lowest()
. Согласно стандарту он возвращает именно то, что вы ищете:
Конечное значение x такое, что не существует другого конечного значения y, где
y < x
.
Имеет значение для всех специализаций, в которыхis_bounded != false
.
Есть много ответов -std::numeric_limits<double>::max()
.
К счастью, в большинстве случаев они подойдут. В схемах кодирования с плавающей запятой число разлагается на мантиссу и показатель степени, и большинство из них (например, популярный IEEE-754 ) используют отдельный знаковый бит, который не принадлежит мантиссе. Это позволяет преобразовать самый большой положительный результат в самый маленький отрицательный, просто перевернув знак:
Стандарт не устанавливает никаких стандартов с плавающей запятой.
Я согласен с тем, что мой аргумент является немного теоретическим, но предположим, что какой-нибудь эксцентричный производитель компиляторов будет использовать революционную схему кодирования с мантиссой, закодированной в некоторых вариантах дополнения до двух. . Кодирование с дополнением до двух не является симметричным. например, для 8-битного символа со знаком максимальное положительное значение - 127, а минимальное отрицательное - -128. Таким образом, мы могли представить себе некоторую кодировку с плавающей запятой, показывающую подобное асимметричное поведение.
Я не знаю ни одной такой схемы кодирования, но дело в том, что что стандарт не гарантирует, что смена знака даст желаемый результат . Так что этот популярный ответ (извините, ребята!) Нельзя рассматривать как полностью портативное стандартное решение! / * по крайней мере, если вы не утверждали, что numeric_limits<double>::is_iec559
это правда * /
Исходный вопрос касается бесконечности. Итак, почему бы не использовать
#define Infinity ((double)(42 / 0.0))
согласно определению IEEE? Вы, конечно, можете отрицать это.
numeric_limits<double>::has_infinity && ! numeric_limits<double>::traps
Существует ли стандартный и / или переносимый способ представления наименьшего отрицательного значения (например, использование отрицательной бесконечности) в программе на C (++)?
C. подход.
Многие реализации поддерживают +/- бесконечности, поэтому самое отрицательное double
значение -INFINITY
.
#include <math.h>
double most_negative = -INFINITY;
Есть стандартный и / или портативный способ ....?
Теперь нам нужно рассмотреть и другие случаи:
Просто -DBL_MAX
.
Я ожидал, что в этом случае OP предпочтет -DBL_MAX
.
DBL_MAX
.Это необычный случай, вероятно, не имеющий отношения к OP. Когда double
кодируется как пара с плавающей запятой для достижения желаемого диапазона / прецессии (см. Double-double ), существует максимальное нормальное значение double
и, возможно, большее ненормальное . Я видел дебаты, DBL_MAX
следует ли ссылаться на величайший нормальный , величайшему из обоих.
К счастью, этот парный подход обычно включает -infinity, поэтому остается наиболее отрицательное значение -INFINITY
.
Для большей переносимости код может пойти по пути
// HUGE_VAL is designed to be infinity or DBL_MAX (when infinites are not implemented)
// .. yet is problematic with unsigned infinity.
double most_negative1 = -HUGE_VAL;
// Fairly portable, unless system does not understand "INF"
double most_negative2 = strtod("-INF", (char **) NULL);
// Pragmatic
double most_negative3 = strtod("-1.0e999999999", (char **) NULL);
// Somewhat time-consuming
double most_negative4 = pow(-DBL_MAX, 0xFFFF /* odd value */);
// My suggestion
double most_negative5 = (-DBL_MAX)*DBL_MAX;
Если у вас не включены исключения с плавающей запятой (чего не следует имхо), вы можете просто сказать:
double neg_inf = -1/0.0;
Это дает отрицательную бесконечность. Если вам нужен float, вы можете преобразовать результат
float neg_inf = (float)-1/0.0;
или используйте арифметику одинарной точности
float neg_inf = -1.0f/0.0f;
Результат всегда один и тот же, существует ровно одно представление отрицательной бесконечности как с одинарной, так и с двойной точностью, и они преобразуются друг в друга, как и следовало ожидать.
-INFINITY
neg_inf
он инициализируется постоянным значением . Компилятор позаботится о вычислении inf
значения. И когда вы используете его как нулевое значение для вычисления максимума, первая итерация обычно перезаписывает его с большим значением. Т.е. производительность вряд ли проблема. И ОП конкретно спрашивает о «например, использовать отрицательную бесконечность», и -inf
это действительно единственный правильный ответ на этот вопрос. Вы проголосовали против правильного и полезного ответа.