3

考虑两种计​​算方式:

  1. 双精度数据
    -> 应用具有双精度临时函数的函数
    -> 返回结果
  2. 双精度数据
    -> 转换为 long double
    -> 应用具有长双精度临时函数的函数
    -> 转换为 double
    -> 返回结果

与第一个解决方案相比,第二种解决方案能否给出不太准确的结果?如果是,在什么情况下?

4

2 回答 2

5

是的。证明:令 c = 0x1p-53 + 0x1p-64。以双精度和长双精度计算 1+cc-1(常见的 Intel 格式,具有 64 位有效位)。在 double 中,结果为 0,这是数学上精确的答案。在 long double 中,结果是 -0x1p-64,这是错误的(并且在转换为 double 时仍然是错误的)。

在 double 中,1+c 将 1 的 ULP(最小精度单位)的一半添加到 1,因此它产生 1 加上一个 ULP。减去 c 会减去 ULP 的一半多一点,因此与结果最接近的可表示数字(双精度数)是 1,因此产生 1。然后减去 1 得到 0。

In long double, 1+c adds 0x1p-53 plus half an ULP of 1. (In long double, the ULP of 1 is 0x1p-63.) Since the result is exactly the same distance from the two nearest representable numbers (in long double), the one with the low bit zero is returned, 1+0x1p-53. Then the exact result of subtracting c is 1 - 0x1p-64. This is exactly representable, so it is returned. Finally, subtracting 1 yields -0x1p-64.

于 2012-05-28T00:06:47.583 回答
0

关于long double草案说:

3.9.1 基本类型

8浮点类型共有三种:float、double 和 long double。double 类型提供的精度至少与 float 一样,long double 类型提供的精度至少与 double 一样。float 类型的值集是 double 类型的值集的子集;double 类型的值集是 long double 类型的值集的子集。浮点类型的值表示是实现定义的。整数和浮点类型统称为算术类型。标准模板 std::numeric_limits (18.3) 的特化应指定实现的每种算术类型的最大值和最小值。

至于下一个最有趣的促销活动:

4.6 浮点推广

1 float 类型的纯右值可以转换为 double 类型的纯右值。值不变。

2这种转换称为浮点提升。

请注意,没有什么要说doublelong double。不过,我会冒这个险。

long double接下来关于转换,当您从到时,我们感兴趣的是double

4.8 浮点数转换

1浮点类型的纯右值可以转换为另一种浮点类型的纯右值。如果源值可以在目标类型中精确表示,则转换的结果就是该精确表示。如果源值介于两个相邻的目标值之间,则转换的结果是实现定义的选择这些值中的任何一个。否则,行为未定义。

2允许作为浮点提升的转换不包括在浮点转换集中。

现在,让我们看看缩小的效果:

6 . 缩小转换是隐式转换

[...]

  • 从long double到double或者float,或者从double到float,除非源是常量表达式并且转换后的实际值在可以表示的值范围内(即使不能准确表示)

所有这些标准语都有两个要点:

  • 将关于缩小的部分与关于实现定义的转换的部分结合起来,您的结果可能会在跨平台时发生变化。
  • 如果您的中间结果(考虑到多个此类结果)在long doublea double(高或低)无法准确表示的范围内,则这些结果可以累积以返回不同的最终结果,您希望将其作为double.

至于哪个更准确,我认为这完全取决于您的应用程序。

于 2012-05-27T16:53:25.580 回答