c - 就浮点而言,是否有正确的常量表达式用于其最高有效位?

标签 c floating-point constant-expression

问题:给定一个浮点常量表达式,我们可以编写一个宏来计算一个常量表达式,该常量表达式的值是等于尾数最高位的 2 的幂吗?同样,这只是小于或等于输入幅度的两个的最大幂。

就这个问题而言,我们可以忽略:

  • 接近溢出或接近下溢的值(可以通过有限多次应用 ?: 来重新缩放)。
  • 负输入(可以同样处理)。
  • 不符合Annex-F标准的实现(实际上不能用它们做任何有用的浮点运算)。
  • 关于精度过高的怪异(float_tdouble_t 可以与 FLT_EVAL_METHOD 和其他 float.h 宏一起使用以安全地处理它)。

因此,只要解决远离无穷大和非正规范围的正值问题就足够了。

请注意,此问题相当于查找特定值的“epsilon”,即 nextafter(x,INF)-x (或 float 中的等效项) > 或 long double),结果仅按 DBL_EPSILON(或该类型的等效值)缩放。如果解决方案更简单,则完全可以接受。

我有一个建议的解决方案作为 self 回答发布,但我不确定它是否正确。

最佳答案

如果您可以假设 IEEE 754 二进制 64 格式和语义(特别是算术运算正确舍入)以及舍入到偶数舍入模式,那么这是一个很好的事实对于任何不太小也不太大的正有限doublex ,从 x 开始的下一个可表示值总是由 x / 0x1.fffffffffffffp-1 给出(其中 0x1.fffffffffffffp-1 只是拼写为十六进制文字的 1.0 - 0.5 * DBL_EPSILON)。

因此,我们可以简单地从以下位置获得您要求的最高有效位:

(x / 0x1.fffffffffffffp-1 - x) * 0x1.0p+52

当然,float 也有类似的结果。 ,假设 IEEE 754 binary32 格式和语义。

事实上,唯一失败的正常正值是 DBL_MAX ,除法结果溢出到无穷大。

要证明除法技巧有效,只要证明x就足够了。在 1.0 <= x < 2.0 范围内;很容易证明对于任何 x在此范围内,x / 0x1.fffffffffffffp-1 - x的值(其中 / 在本例中表示数学除法)位于半开区间 (2^-53, 2^52] 内,因此在舍入到偶数(或实际上任何舍入到最近的舍入模式)下,x / 0x1.fffffffffffffp-1四舍五入到下一个可表示的值。

同样,在相同的假设下,x * 0x1.fffffffffffffp-1始终是从 x 开始的下一个可表示值.

关于c - 就浮点而言,是否有正确的常量表达式用于其最高有效位?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53598657/

相关文章:

c - 每三次运行我的程序时出现段错误,使用 malloc

检查两个 char 数组元素是否相同 c

Haskell 最小/最大双常数

检查 double 是否可以被 C 中的另一个 double 整除?

c#:什么是常量表达式?

c - "Warning: return makes integer from pointer without a cast"在 C 中是什么意思?

c# - 如何在我的 C# 代码中调用库中的 C 方法?

c++ - 如果两个分数的分母都是 2 的幂,我可以比较两个分数吗

c++ - 如何使用 const 成员变量设置数组大小?

c++ - `*' 不能出现在常量表达式中