附加的x + x
是否可以与IEEE 754(IEC 559)浮点标准中的乘法2 * x
互换,或更一般地说,是否可以保证case_add
和case_mul
始终给出完全相同的结果?
#include <limits>
template <typename T>
T case_add(T x, size_t n)
{
static_assert(std::numeric_limits<T>::is_iec559, "invalid type");
T result(x);
for (size_t i = 1; i < n; ++i)
{
result += x;
}
return result;
}
template <typename T>
T case_mul(T x, size_t n)
{
static_assert(std::numeric_limits<T>::is_iec559, "invalid type");
return x * static_cast<T>(n);
}
最佳答案
是的,因为它们在数学上是相同的,所以它们将给出相同的结果(因为结果在浮点数中是精确的)。
一般而言,不。据我所知,n <= 5
似乎成立了:
n=3
:因为x+x
是精确的(即不涉及四舍五入),所以(x+x)+x
在最后一步仅涉及一个四舍五入。 n=4
(并且您使用的是默认的舍入模式),然后x
的最后一位为0,则x+x+x
是精确的,因此结果与n=3
相同,因此结果相同。 01
,则x+x+x
的确切值将具有1|1
的最后2位(其中|表示格式的最后一位),将四舍五入为0|0
。下一个加法将给出精确的结果|01
,因此结果将四舍五入,以消除上一个错误。 11
,则x+x+x
的确切值将具有0|1
的最后2位,将四舍五入为0|0
。下一个加法将给出精确的结果|11
,因此结果将被四舍五入,再次消除上一个错误。 n=5
(同样,假设使用默认的四舍五入方法):由于x+x+x+x
是精确的,因此其持有的原因与n=3
相同。 对于
n=6
,它会失败,例如将x
设为1.0000000000000002
(double
之后的下一个1.0
),在这种情况下,6x
是6.000000000000002
,而x+x+x+x+x+x
是6.000000000000001
关于c++ - IEEE 754浮点加法和乘法的互换性,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39855825/