C/C++ 中的最小双精度值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1153548/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
minimum double value in C/C++
提问by Will
Is there a standard and/or portable way to represent the smallest negative value (e.g. to use negative infinity) in a C(++) program?
在 C(++) 程序中是否有标准和/或可移植的方式来表示最小的负值(例如使用负无穷大)?
DBL_MIN in float.h is the smallest positivenumber.
float.h 中的 DBL_MIN 是最小的正数。
回答by dfa
-DBL_MAX
in ANSI C, which is defined in float.h.
-DBL_MAX
在 ANSI C 中,它在 float.h 中定义。
回答by fortran
Floating point numbers (IEEE 754) are symmetrical, so if you can represent the greatest value (DBL_MAX
or numeric_limits<double>::max()
), just prepend a minus sign.
浮点数 (IEEE 754) 是对称的,因此如果您可以表示最大值(DBL_MAX
或numeric_limits<double>::max()
),只需在前面加上一个减号。
And then is the cool way:
然后是很酷的方式:
double f;
(*((long long*)&f))= ~(1LL<<52);
回答by rubenvb
In C, use
在 C 中,使用
#include <float.h>
const double lowest_double = -DBL_MAX;
In C++pre-11, use
在 C++pre-11 中,使用
#include <limits>
const double lowest_double = -std::numeric_limits<double>::max();
In C++11 and onwards, use
在 C++11 及更高版本中,使用
#include <limits>
constexpr double lowest_double = std::numeric_limits<double>::lowest();
回答by Andrew Hare
Try this:
尝试这个:
-1 * numeric_limits<double>::max()
Reference: numeric_limits
参考: numeric_limits
This class is specialized for each of the fundamental types, with its members returning or set to the different values that define the properties that type has in the specific platform in which it compiles.
此类专门用于每种基本类型,其成员返回或设置为不同的值,这些值定义了该类型在其编译的特定平台中具有的属性。
回答by Christoph
Are you looking for actual infinity or the minimal finite value? If the former, use
您是在寻找实际无穷大还是最小有限值?如果是前者,请使用
-numeric_limits<double>::infinity()
which only works if
这只适用于
numeric_limits<double>::has_infinity
Otherwise, you should use
否则,你应该使用
numeric_limits<double>::lowest()
which was introduces in C++11.
这是在 C++11 中引入的。
If lowest()
is not available, you can fall back to
如果lowest()
不可用,您可以回退到
-numeric_limits<double>::max()
which may differ from lowest()
in principle, but normally doesn't in practice.
这可能与lowest()
原则不同,但在实践中通常不会。
回答by Christophe
A truly portable C++ solution
真正可移植的 C++ 解决方案
As from C++11 you can use numeric_limits<double>::lowest()
.
According to the standard, it returns exactly what you're looking for:
从 C++11 开始,您可以使用 numeric_limits<double>::lowest()
. 根据标准,它会准确返回您要查找的内容:
A finite value x such that there is no other finite value y where
y < x
.
Meaningful for all specializations in whichis_bounded != false
.
一个有限值 x 使得没有其他有限值 y 其中
y < x
。
对所有专业都有意义,其中is_bounded != false
.
Lots of non portable C++ answers here !
这里有很多不可移植的 C++ 答案!
There are many answers going for -std::numeric_limits<double>::max()
.
有很多答案-std::numeric_limits<double>::max()
。
Fortunately, they will work well in most of the cases. Floating point encoding schemes decompose a number in a mantissa and an exponent and most of them (e.g. the popular IEEE-754) use a distinct sign bit, which doesn't belong to the mantissa. This allows to transform the largest positive in the smallest negative just by flipping the sign:
幸运的是,它们在大多数情况下都能很好地工作。浮点编码方案在尾数和指数中分解一个数字,其中大多数(例如流行的IEEE-754)使用不同的符号位,它不属于尾数。这允许通过翻转符号将最大的正数转换为最小的负数:
Why aren't these portable ?
为什么这些不便携?
The standard doesn't impose any floating point standard.
该标准不强加任何浮点标准。
I agree that my argument is a little bit theoretic, but suppose that some excentric compiler maker would use a revolutionary encoding scheme with a mantissa encoded in some variations of a two's complement. Two's complement encoding are not symmetric. for example for a signed 8 bit char the maximum positive is 127, but the minimum negative is -128. So we could imagine some floating point encoding show similar asymmetric behavior.
我同意我的论点有点理论性,但假设某些偏心的编译器制造商会使用革命性的编码方案,其尾数以二进制补码的某些变体编码。二进制补码编码不是对称的。例如,对于有符号的 8 位字符,最大正数为 127,但最小负数为 -128。所以我们可以想象一些浮点编码表现出类似的非对称行为。
I'm not aware of any encoding scheme like that, but the point is that the standard doesn't guarantee that the sign flipping yields the intended result. So this popular answer (sorry guys !) can't be considered as fully portable standard solution ! /* at least not if you didn't assert that numeric_limits<double>::is_iec559
is true */
我不知道有任何类似的编码方案,但关键是标准不保证符号翻转会产生预期的结果。所以这个流行的答案(对不起,伙计们!)不能被视为完全便携的标准解决方案!/* 至少如果你没有断言这numeric_limits<double>::is_iec559
是真的 */
回答by MadH
回答by Norbert
The original question concerns infinity. So, why not use
最初的问题涉及无穷大。那么,为什么不使用
#define Infinity ((double)(42 / 0.0))
according to the IEEE definition? You can negate that of course.
根据 IEEE 定义?你当然可以否定这一点。
回答by chux - Reinstate Monica
Is there a standard and/or portable way to represent the smallest negative value (e.g. to use negative infinity) in a C(++) program?
在 C(++) 程序中是否有标准和/或可移植的方式来表示最小的负值(例如使用负无穷大)?
C approach.
C 方法。
Many implementations support +/- infinities, so the most negative double
value is -INFINITY
.
许多实现支持 +/- 无穷大,因此最负的double
值是-INFINITY
。
#include <math.h>
double most_negative = -INFINITY;
Is there a standard and/or portable way ....?
是否有标准和/或便携式方式....?
Now we need to also consider other cases:
现在我们还需要考虑其他情况:
- No infinities
- 没有无穷大
Simply -DBL_MAX
.
简直了-DBL_MAX
。
- Only an unsignedinfinity.
- 只有一个无符号无穷大。
I'd expect in this case, OP would prefer -DBL_MAX
.
我希望在这种情况下,OP 更喜欢-DBL_MAX
.
- De-normal values greater in magnitude than
DBL_MAX
.
- 非正常值的量级大于
DBL_MAX
。
This is an unusual case, likely outside OP's concern. When double
is encoded as a pair of a floating pointsto achieve desired range/precession, (see double-double) there exist a maximum normaldouble
and perhaps a greater de-normalone. I have seen debate if DBL_MAX
should refer to the greatest normal, of the greatest of both.
这是一个不寻常的案例,可能不在 OP 的关注范围内。当double
被编码为一对浮点数以实现所需的范围/进动时,(请参阅double-double)存在最大法线,double
并且可能存在更大的非正则。我见过辩论是否DBL_MAX
应该指最大的正常,两者中最伟大的。
Fortunately this paired approach usually includes an -infinity, so the most negative value remains -INFINITY
.
幸运的是,这种配对方法通常包含一个 -无穷大,因此最负的值仍然是-INFINITY
。
For more portability, code can go down the route
为了更多的可移植性,代码可以沿着这条路线走
// 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;
回答by cmaster - reinstate monica
If you do not have float exceptions enabled (which you shouldn't imho), you can simply say:
如果您没有启用浮动异常(您不应该恕我直言),您可以简单地说:
double neg_inf = -1/0.0;
This yields negative infinity. If you need a float, you can either cast the result
这产生负无穷大。如果你需要一个浮点数,你可以转换结果
float neg_inf = (float)-1/0.0;
or use single precision arithmetic
或使用单精度算术
float neg_inf = -1.0f/0.0f;
The result is always the same, there is exactly one representation of negative infinity in both single and double precision, and they convert to each other as you would expect.
结果总是相同的,在单精度和双精度中都只有一种负无穷大的表示,并且它们可以按照您的预期相互转换。