Чи існує стандартний та / або портативний спосіб представити найменше негативне значення (наприклад, використовувати негативну нескінченність) у програмі на 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 ++ pre-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? Ви можете це заперечити, звичайно.
Чи існує стандартний та / або портативний спосіб представити найменше негативне значення (наприклад, використовувати негативну нескінченність) у програмі на C (++)?
С підхід.
Багато реалізацій підтримують +/- нескінченності, тому найбільш негативним double
є значення -INFINITY
.
#include <math.h>
double most_negative = -INFINITY;
Чи існує стандартний та / або портативний спосіб ....?
Тепер нам потрібно також розглянути інші випадки:
Просто -DBL_MAX
.
Я б очікував, що в цьому випадку OP воліє -DBL_MAX
.
DBL_MAX
.Це незвичний випадок, який, ймовірно, не стосується ОП. Коли double
кодується як пара плаваючих точок для досягнення бажаного діапазону / прецесії, (див. Подвійний-подвійний ) існує максимальна нормальна double
і, можливо, більша нормальна . Я бачив суперечки, чи DBL_MAX
слід посилатися на найбільше нормальне , з найбільшого з обох.
На щастя, цей парний підхід зазвичай містить -нескінченність, тому найбільш негативне значення залишається -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 neg_inf = (float)-1/0.0;
або використовувати одиничну точну арифметику
float neg_inf = -1.0f/0.0f;
Результат завжди однаковий, є рівно одне подання негативної нескінченності як в одинарній, так і в подвійній точності, і вони перетворюються один на одного, як і слід було очікувати.
-INFINITY
neg_inf
ініціалізується до постійного значення . Компілятор подбає про обчислення inf
значення. І коли ви використовуєте його як нульове значення для обчислення макс., Перша ітерація, як правило, перезапише його з більшим значенням. Тобто продуктивність навряд чи є проблемою. І ОП запитує конкретно про "наприклад, використовувати негативну нескінченність", і -inf
справді є єдиною правильною відповіддю на це. Ви підтримали правильну та корисну відповідь.