C ++转换为更精确的类型并失去准确性?

时间:2012-05-27 16:04:59

标签: c++ floating-point precision

考虑两种计​​算方式:

  1. 双精度数据
    - >应用双精度临时功能
    - >返回结果
  2. 双精度数据
    - >施加长双 - >应用具有长双精度临时值的功能
    - >施加双 - >返回结果
  3. 与第一个解决方案相比,第二个解决方案能否提供不太准确的结果?如果是,在什么情况下是?

2 个答案:

答案 0 :(得分:5)

是。证明:设c = 0x1p-53 + 0x1p-64。以double和long double(普通Intel格式,64位有效数字)评估1 + c-c-1。在double中,结果为0,这是数学上准确的答案。在long double中,结果是-0x1p-64,这是错误的(当转换为double时仍然是错误的。)

在double中,1 + c增加略多于ULP(最低精度单位)的一半,即1到1,因此它产生1加上ULP。减去c减去略多于ULP的一半,因此结果中最接近的可表示数字(以double为单位)为1,因此产生1。然后减去1得到0。

在long double中,1 + c增加0x1p-53加上一半ULP为1.(在long double中,1的ULP为0x1p-63。)因为结果与两个最接近的可表示数字的距离完全相同(在long double中),返回低位0的那个,1 + 0x1p-53。然后减去c的确切结果是1 - 0x1p-64。这是完全可以表示的,因此返回。最后,减去1会产生-0x1p-64。

答案 1 :(得分: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类型的prvalue可以转换为类型的prvalue   双。价值没有变化。

     

2 此转化称为浮动   点推广。

请注意,doublelong double没有任何关系。我觉得这只是一个漏洞。

接下来介绍从long doubledouble时我们感兴趣的转化次数:

  

4.8浮点转换

     

1 浮点类型的prvalue可以转换为prvalue   另一种浮点类型。如果源值可以准确   在目标类型中表示,转换的结果是   确切的表示。如果源值在两个相邻之间   目的地值,转换的结果是   实现定义的这两个值的选择。除此以外,   行为未定义。

     

2 允许转换为浮点数   促销活动将从浮点转化集中排除。

现在,让我们看看缩小的影响:

  

<强> 6 即可。缩小转换是隐式转换

     

[...]

     
      
  • 从long double到double或float,或从double到float,除非source是一个常量表达式,后面是实际值   转换在可以表示的值范围内(甚至   如果无法准确表示的话)
  •   

所有这些标准中有两个要点:

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

至于哪个更准确,我认为这完全取决于你的申请。