[英]Interchangeability of IEEE 754 floating-point addition and multiplication
加法x + x
可以通過IEEE 754(IEC 559)浮點標准中的乘法2 * x
x + 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);
}
加法
x + x
可通過IEEE 754(IEC 559)浮點標准中的乘法2 * x
x + x
互換
是的,因為它們在數學上都是相同的,所以它們將給出相同的結果(因為結果在浮點中是精確的)。
或者更一般地說,是否有任何保證case_add和case_mul始終給出完全相同的結果?
不一般,沒有。 據我所知,它似乎適用於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
( 1.0
之后的下一個double
6.000000000000002
),在這種情況下, 6x
為6.000000000000002
, x+x+x+x+x+x
為6.000000000000001
如果n
是例如pow(2, 54)
則乘法將正常工作,但是在加法路徑中,一旦結果值足夠大於輸入x
, result += x
將產生result
。
是的,但它並不普遍。 乘以高於2的數字可能不會給出相同的結果,因為您更改了指數,如果替換為adds,則可能會略微下降。 但是,如果由添加操作替換,乘以2則不會丟失一點。
如果case_add
的累加器result
變得太大,則添加x
將引入舍入誤差。 在某個時刻,添加x
根本不會產生任何影響。 所以函數不會給出相同的結果。
例如,如果double x = 0x1.0000000000001p0
(十六進制浮點表示法):
n case_add case_mul
1 0x1.0000000000001p+0 0x1.0000000000001p+0
2 0x1.0000000000001p+1 0x1.0000000000001p+1
3 0x1.8000000000002p+1 0x1.8000000000002p+1
4 0x1.0000000000001p+2 0x1.0000000000001p+2
5 0x1.4000000000001p+2 0x1.4000000000001p+2
6 0x1.8000000000001p+2 0x1.8000000000002p+2
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.