在C(++)程序中是否存在标准和/或可移植的方法来表示最小的负值(例如,使用负无穷大)?
float.h中的DBL_MIN是最小的正数。
在C(++)程序中是否存在标准和/或可移植的方法来表示最小的负值(例如,使用负无穷大)?
float.h中的DBL_MIN是最小的正数。
Answers:
-DBL_MAX
在ANSI C中定义,它在float.h中定义。
-DBL_MAX
可以精确表示,因此,如果FP硬件不具备此功能,则实现只能解决该问题。请参阅5.2.4.2.2中C99的浮点类型<float.h> p2的特征(此后可能已移至其他地方)。
浮点数(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
在幅度上的最小正值和在幅度上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)使用一个不属于尾数的独特符号位。只需翻转符号,就可以将最大的正数转换为最小的负数:
该标准不强加任何浮点标准。
我同意我的观点有点理论上的观点,但是假设某些偏心的编译器制造商将使用革命性的编码方案,尾数以a的一些变体进行编码。 二进制补码的体。二进制补码不对称。例如,对于带符号的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;
如果您没有启用float异常(不应该恕我直言),则可以简单地说:
double neg_inf = -1/0.0;
这产生负无穷大。如果需要浮点数,则可以强制转换结果
float neg_inf = (float)-1/0.0;
或使用单精度算术
float neg_inf = -1.0f/0.0f;
结果始终是相同的,单精度和双精度都有一个负无穷大的表示形式,并且它们可以按照您的期望相互转换。
-INFINITY
neg_inf
已初始化为一个常量值。编译器将负责计算inf
值。而且当您将其用作计算最大值的空值时,第一次迭代通常会使用较大的值覆盖它。即性能几乎不是问题。OP专门询问“例如使用负无穷大”,-inf
这确实是对此的唯一正确答案。您否决了正确且有用的答案。