C/C++中的最小双精度值

Wil*_*ill 78 c c++ math

是否有标准和/或可移植的方式来表示C(++)程序中最小的负值(例如,使用负无穷大)?

float.h中的DBL_MIN是最小的数.

dfa*_*dfa 120

-DBL_MAX 在ANSI C中,在float.h中定义.

  • downvotes是无意义的解释 (14认同)
  • @j_random_hacker这是一个非常好的观点,但是C标准要求`-DBL_MAX`是完全可表示的,所以如果FP硬件不具备这个能力,那么实现就必须解决它.请参阅*5.2.4.2.2中的浮点模型C99的浮动类型<float.h> p2*的特征(从那时起可能已经移动到其他位置). (2认同)
  • @j_random_hacker是的,但是p2指定e_min和e_max独立于符号位,所以`DBL_MAX`正好是(1-b ^ -p)b ^ e_max,这是完全可表示的,最负的有限值正是 - ( 1 - b ^ -p)b ^ e_max,并且由于恰好是`-DBL_MAX`,否则`DBL_MAX`也不会引入任何舍入错误. (2认同)

for*_*ran 70

浮点数(IEEE 754)是对称的,因此如果您可以表示最大值(DBL_MAXnumeric_limits<double>::max()),则只需加一个减号.

然后是很酷的方式:

double f;
(*((long long*)&f))= ~(1LL<<52);
Run Code Online (Sandbox Code Playgroud)

  • +1用于指出浮点数的对称性:) (6认同)
  • 那些不使用IEEE 754浮点数的C/C++实现呢? (4认同)
  • 这意味着实现不使用IEEE 754算法,但公平地说这些选项仍然使用IEEE表示.您可能会发现一些使用非IEEE表示的仿真库,因为并非所有处理器都具有本机浮点格式(尽管它们可能会发布包含格式的C ABI,对应于制造商提供的仿真库).因此,并非所有编译器都可以使用一个.当您要求"标准和/或便携式"时,仅仅取决于您的意思,原则上便携并且在实践中便携. (4认同)
  • 您对IEEE 754的说法是正确的,但该标准不要求使用此编码(正如@SteveJessop指出的那样,实际上便携式原则上与便携式不同). (3认同)
  • gcc 的 -ffast-math 手册说“设置 -fno-math-errno、-funsafe-math-optimizations、-ffinite-math-only、-fno-rounding-math、-fno-signaling-nans 和 -fcx-limited- range 此选项不会被任何 -O 选项打开,因为它可能会导致程序输出不正确,而这些程序依赖于数学函数的 IEEE 或 ISO 规则/规范的精确实现。但是,它可能会为执行以下操作的程序生成更快的代码:不需要这些规范的保证。” 快速数学是一种常见的设置,例如英特尔 ICC 就默认使用它。总而言之,不确定这对我意味着什么:-) (2认同)

rub*_*nvb 40

在C中,使用

#include <float.h>

const double lowest_double = -DBL_MAX;
Run Code Online (Sandbox Code Playgroud)

在C++ pre-11中,使用

#include <limits>

const double lowest_double = -std::numeric_limits<double>::max();
Run Code Online (Sandbox Code Playgroud)

在C++ 11及更高版本中,使用

#include <limits>

constexpr double lowest_double = std::numeric_limits<double>::lowest();
Run Code Online (Sandbox Code Playgroud)

  • @Alexis:如果你看一下你所链接页面上表格中最下面的三行,你会看到`min`在数量上给你最小的正值,而'lower`在数量上是最大的负值.是的,这太可怕了.欢迎来到C++标准库`:-P`的辉煌世界. (5认同)

And*_*are 32

试试这个:

-1 * numeric_limits<double>::max()
Run Code Online (Sandbox Code Playgroud)

参考: numeric_limits

此类专门用于每个基本类型,其成员返回或设置为不同的值,这些值定义类型在其编译的特定平台中具有的属性.

  • @ k06a在这样一个长表达式中由单个字符表示的否定,其中字符串甚至表示"max",肯定迟早会得到某个人.要么存储在描述性变量中,要么使用"-1*..."使其更清晰. (3认同)

Chr*_*oph 20

您在寻找实际无穷大还是最小有限值?如果是前者,请使用

-numeric_limits<double>::infinity()
Run Code Online (Sandbox Code Playgroud)

这只适用于

numeric_limits<double>::has_infinity
Run Code Online (Sandbox Code Playgroud)

否则,你应该使用

numeric_limits<double>::lowest()
Run Code Online (Sandbox Code Playgroud)

这是在C++ 11中引入的.

如果lowest()没有,你可以回头

-numeric_limits<double>::max()
Run Code Online (Sandbox Code Playgroud)

这可能与lowest()原则上不同,但通常在实践中不同.


Chr*_*phe 9

真正可移植的C++解决方案

从C++ 11开始,您可以使用 numeric_limits<double>::lowest().根据标准,它会返回您正在寻找的内容:

有限值x使得在其中没有其他有限值y y < x.
对于所有专业都有意义is_bounded != false.

在线演示


这里有很多不可移植的C++答案!

有很多答案可供选择-std::numeric_limits<double>::max().

幸运的是,它们在大多数情况下都能很好地工作.浮点编码方案在尾数和指数中分解数字,并且它们中的大多数(例如,流行的IEEE-754)使用不属于尾数的不同符号位.这允许通过翻转符号来转换最小负数中的最大正数:

在此输入图像描述

为什么这些不便携?

该标准不强加任何浮点标准.

我同意我的论点有点理论,但是假设某个偏心编译器制造商会使用革命性的编码方案,其中尾数编码为二进制补码的某些变.二进制补码编码不对称.例如,对于带符号的8位字符,最大正数为127,但最小负数为-128.所以我们可以想象一些浮点编码显示类似的不对称行为.

我不知道任何类似的编码方案,但重点是标准不能保证符号翻转产生预期的结果.所以这个流行的答案(对不起家伙!)不能算是完全便携的标准解决方案!/*至少不是如果你没有断言那numeric_limits<double>::is_iec559是真的*/


Mad*_*adH 7

- std::numeric_limits<double>::max()
Run Code Online (Sandbox Code Playgroud)

应该工作得很好

数字限制