考虑两种计算方式:
与第一个解决方案相比,第二个解决方案能否提供不太准确的结果?如果是,在什么情况下是?
答案 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 此转化称为浮动 点推广。
请注意,double
与long double
没有任何关系。我觉得这只是一个漏洞。
接下来介绍从long double
到double
时我们感兴趣的转化次数:
4.8浮点转换
1 浮点类型的prvalue可以转换为prvalue 另一种浮点类型。如果源值可以准确 在目标类型中表示,转换的结果是 确切的表示。如果源值在两个相邻之间 目的地值,转换的结果是 实现定义的这两个值的选择。除此以外, 行为未定义。
2 允许转换为浮点数 促销活动将从浮点转化集中排除。
现在,让我们看看缩小的影响:
<强> 6 即可。缩小转换是隐式转换
[...]
- 从long double到double或float,或从double到float,除非source是一个常量表达式,后面是实际值 转换在可以表示的值范围内(甚至 如果无法准确表示的话)
所有这些标准中有两个要点:
long double
中的中间结果(考虑多个此类结果)在double
(高或低)无法准确表示的范围内,则这些结果会累积以返回不同的最终结果您希望以double
返回。至于哪个更准确,我认为这完全取决于你的申请。