代码之家  ›  专栏  ›  技术社区  ›  Anonymous

如何找到每两个值产生较小输出的乘数?

  •  6
  • Anonymous  · 技术社区  · 6 年前

    C 使得每个IEEE-754乘积都是正的,标准化的二进制-64值 A 具有 C类 小于 一个 ?

    假设四舍五入到最近,则为偶数。

    2 回复  |  直到 5 年前
        1
  •  5
  •   Sneftel    6 年前

    有一些实验方法;这里有一个证据 C = 1 - ε ε 是机器epsilon(即 1 最小可表示数大于 1个

    我们知道 C < 1 ,当然,所以尝试 C = 1 - ε/2 因为它是下一个小于 . (在 ε/2 是因为 C 是在 [0.5, 1) A .

    在这一段中我假设 1 <= A < 2 . 如果两者都是 一个 AC 在“正常”区域,那么指数是什么并不重要,情况与指数相同 2^0 . 现在,选择 C类 显然对 A=1 ,所以我们只剩下这个区域了 1 < A < 2 A = 1 + ε ,我们看到了 (精确值,而不是四舍五入的结果)已经大于1;并且 A = 2 - ε 我们看到它小于2。这很重要,因为如果 自动控制 自动控制 round(AC) (即四舍五入到最接近的可表示值)最多 /2个 . 现在,如果 A - AC < ε/2 ,然后 round(AC) = A 不要 A - AC = ε/2 那么它 可以 一个 考虑到常规FP舍入规则的“偶数”部分,但让我们看看是否可以做得更好) C=1-/2 ,我们可以看到 A - AC = A - A(1 - ε/2) = A * ε/2 /2个 (记住, A>1 ),离这里足够远了 一个 绕开它。

    一个 我们要检查的是最小的正常值,因为 在正常范围内,因此我们的“相对最近距离”规则不适用。我们发现在那种情况下 A-AC 正好是该地区机器epsilon的一半。”四舍五入, 与偶数的关系 一个 . 德拉特。

    经历同样的事情 C=1- round(AC) < A 没有任何东西能接近 一个 (我们最后问 A * ε > ε/2 C = 1-ε/2 几乎 C = 1-ε 把我们带到终点。

        2
  •  0
  •   phuclv    5 年前

    由于浮点类型的性质, C 将根据A的值有多大而变化。你可以用 nextafter C类

    但是如果 A A*C 会和A一样。我无法从数学上证明 nextafter(1.0, 0) 对所有可能的A都有效,所以我建议这样的解决方案

    double largestCfor(double A)
    {
        double C = nextafter(1.0, 0);
        while (C*A >= A)
            C = nextafter(C, 0);
        return C;
    }
    

    C类 对任何人都有用的价值 一个 C*A 可能不是最大的可能值,那么您需要检查该类型可以表示的每个指数

    double C = 1;
    for (double A = 0x1p-1022; isfinite(A); A *= 2) // loop through all possible exponents
    {
        double c = largestCfor(A);
        if (c < C) C = c;
    }
    

    我试着继续跑 Ideone

    C                 = 0.999999999999999777955395074969
    nextafter(1.0, 0) = 0.999999999999999888977697537484
    

    编辑:

    0.99999999999999977955395074969是 0x1.ffffffffffffep-1 1 - DBL_EPSILON . 这与斯内夫特上面的证据一致