当前位置: 首页 > 面试题库 >

使用成对求和,我需要多少项才能得出明显错误的结果?

秦权
2023-03-14
问题内容

使用给定的fp数种类,例如float16,直接构造具有完全错误结果的和。例如,使用python / numpy:

import numpy as np

one = np.float16(1)
ope = np.nextafter(one,one+one)

np.array((ope,one,-one,-one)).cumsum()
# array([1.001, 2.   , 1.   , 0.   ], dtype=float16)

在这里,我们习惯于cumsum强制天真的求和。留给自己的设备numpy使用不同的求和顺序,会得到更好的答案:

np.array((ope,one,-one,-one)).sum()
# 0.000977

以上是基于取消。为了排除此类示例,让我们仅允许使用非否定术语。对于幼稚的求和,给出具有非常错误的求和的示例仍然很容易。以下求和10 ^ 4个相同的项,每个项等于10 ^ -4:

np.full(10**4,10**-4,np.float16).cumsum()
# array([1.0e-04, 2.0e-04, 3.0e-04, ..., 2.5e-01, 2.5e-01, 2.5e-01],
  dtype=float16)

最后一项相差4倍。

同样,允许numpy使用成对求和会产生更好的结果:

np.full(10**4,10**-4,np.float16).sum()
# 1.0

可以构造超过成对求和的和。选择分辨率低于1的eps时,我们可以使用1,eps,0,eps,3x0,eps,7x0,eps,15x0,eps,…,但这涉及到疯狂的术语数量。

我的问题:仅使用float16和非否定项,从成对求和中获得至少相差2倍的结果需要多少项。

奖励:同样的问题是“积极”而不是“非消极”。可能吗?


问题答案:

深度1432(因此2 ^ 1432项)足以使真实总和超出计算总和两倍。

我对如何确定所需的术语数量少于两个的想法有个想法。

我们使用动态编程来回答以下问题:给定深度d和目标浮点和s,具有成对和的2^d非负float16s的最大真和是s多少?

让那个数量成为T(d, s)。我们复发

T(0, s) = s,    for all s.
T(d, s) =            max            (T(d-1, a) + T(d-1, b)),    for all d, s.
          a, b : float16(a + b) = s

重复执行的每个步骤都涉及遍历大约2^29组合(因为我们可以假设a ≤ b,并且负浮点数和特殊值超出了限制),并且所需的深度不会超过10^4Hans和您的答案。在我看来可行。

DP代码:

#include <algorithm>
#include <cstdio>
#include <vector>

using Float16 = int;
using Fixed = unsigned long long;

static constexpr int kExponentBits = 5;
static constexpr int kFractionBits = 10;
static constexpr Float16 kInfinity = ((1 << kExponentBits) - 1)
                                     << kFractionBits;

Fixed FixedFromFloat16(Float16 a) {
  int exponent = a >> kFractionBits;
  if (exponent == 0) {
    return a;
  }
  Float16 fraction = a - (exponent << kFractionBits);
  Float16 significand = (1 << kFractionBits) + fraction;
  return static_cast<Fixed>(significand) << (exponent - 1);
}

bool Plus(Float16 a, Float16 b, Float16* c) {
  Fixed exact_sum = FixedFromFloat16(a) + FixedFromFloat16(b);
  int exponent = 64 - kFractionBits - __builtin_clzll(exact_sum);
  if (exponent <= 0) {
    *c = static_cast<Float16>(exact_sum);
    return true;
  }
  Fixed ulp = Fixed{1} << (exponent - 1);
  Fixed remainder = exact_sum & (ulp - 1);
  Fixed rounded_sum = exact_sum - remainder;
  if (2 * remainder > ulp ||
      (2 * remainder == ulp && (rounded_sum & ulp) != 0)) {
    rounded_sum += ulp;
  }
  exponent = 64 - kFractionBits - __builtin_clzll(rounded_sum);
  if (exponent >= (1 << kExponentBits) - 1) {
    return false;
  }
  Float16 significand = rounded_sum >> (exponent - 1);
  Float16 fraction = significand - (Float16{1} << kFractionBits);
  *c = (exponent << kFractionBits) + fraction;
  return true;
}

int main() {
  std::vector<Fixed> greatest0(kInfinity);
  for (Float16 a = 0; a < kInfinity; a++) {
    greatest0[a] = FixedFromFloat16(a);
  }
  for (int depth = 1; true; depth++) {
    auto greatest1 = greatest0;
    for (Float16 a = 1; a < kInfinity; a++) {
      Fixed greatest0_a = greatest0[a];
      for (Float16 b = a; b < kInfinity; b++) {
        Float16 c;
        if (!Plus(a, b, &c)) {
          continue;
        }
        Fixed& value = greatest1[c];
        value = std::max(value, greatest0_a + greatest0[b]);
      }
    }

    std::vector<double> ratios;
    ratios.reserve(kInfinity - 1);
    for (Float16 a = 1; a < kInfinity; a++) {
      ratios.push_back(greatest1[a] / static_cast<double>(FixedFromFloat16(a)));
    }
    std::printf("depth %d, ratio = %.17g\n", depth,
                *std::max_element(ratios.begin(), ratios.end()));
    greatest0.swap(greatest1);
  }
}

我将运行它并在完成后发布更新。



 类似资料:
  • 问题内容: 我想在我的网站上使用我的图像编辑工具。我还需要吗? 我不了解这种情况。如果我不需要它,那么我们什么时候可以同时使用nodejs和angularjs? 问题答案: 您不需要NodeJS即可创建客户端图像编辑工具。 AngularJS是一个由Google和社区维护的Web应用程序框架,可帮助创建单页应用程序,该应用程序由一个HTML页面组成,该页面包含客户端的CSS和JavaScript。

  • 问题内容: 在Python中,当我运行以下代码时: 我收到此错误: 该错误是什么意思? 问题答案: 可能您没有在命令行上提供参数。在这种情况下,只包含一个值,但是必须同时具有两个值才能为和提供值。

  • 问题内容: 我是OSGI的新手,我试图找出解决以下错误的方法 org.osgi.framework.BundleException:包org.foo.serviceBundle中未解决的约束[253]:无法解决253.0:缺少要求[253.0]包;未解决。(&(package = org.slf4j)(版本> = 1.6.0)(!(版本> = 2.0.0))) 我使用了Maven原型来生成包,并在

  • 问题内容: 如果我尝试连接组件而不直接导出,它将无法连接。 例: 为什么这会有什么不同? 问题答案: 对原始组件没有任何作用,而是由高阶组件模式实现的:因此它以React组件为参数,并通过执行需要执行的操作返回另一个组件,例如提供动作创建者和国家作为道具。 因此,当您返回分派返回的组件时,实际上会返回正确的组件。您传递给的组件没有可用的组件。 因此,您可以想到将connect编写为类似

  • 我的代码如下。这是一个学校项目,要求我在不使用语句的情况下完成此操作。我不明白为什么我会犯错误,包括: 代码:

  • 本文向大家介绍你觉得测试和开发需要怎么结合才能使软件的质量得到更好的保障相关面试题,主要包含被问及你觉得测试和开发需要怎么结合才能使软件的质量得到更好的保障时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 测试和开发应该按照W模型的方式进行结合,测试和开发同步进行,能够尽早发现软件缺陷,降低软件开发的成本。 在V模型中,测试过程被加在开发过程的后半部分,单元测试所检测代码的开发是否符合详细设