例如,最初我有這樣的程式碼:
function(x,y){ let z=x+y; . . . }
後來我發現y必須與x相同,想將x y重構為x * 2,但需要保證重構前後整個程式的行為相同。 x x 與 x*2 相同嗎?我不知道 和 * 是否使用不同的計算機制,從而導致舍入到不同的結果。
我測試過:
for(let i=0.01;i<100;i++){ if(i+i!=i*2){ console.log(i); break; } }
對於 i 的某些範圍似乎是正確的,但不知道是否對於所有浮點數都正確。
JavaScript 是ECMAScript 的實現,並且ECMAScript 規範 表示使用IEEE 754 演算法,IEEE-754“雙精度” ”(binary64)格式。第5.2.5 條規定“ ……當應用於數字時,運算符指的是IEEE 754-2019 中的相關運算…」
在IEEE 754 和任何合理的浮點系統中,運算的結果是根據選擇的捨入規則舍入的精確數學結果(例如舍入到最近的聯繫到偶數、舍入到偶數)向零、向上舍入或向下舍入)。 IEEE 754-2019 4.3 說:
由於
x
x
和2•x
具有相同的數學結果,因此浮點運算x x
code> 和2* x
必須產生相同的計算結果。如果應用相同的捨入規則,兩者將得到相同的數學結果,因此計算結果必須相同。上面涵蓋了
x
是數字的情況,包括 ∞和-∞。如果x
是NaN
,則x x
和2*x
也會產生NaN
code>,所以結果又是一樣的。 (請注意,在這種情況下,x x == 2*x
將計算為false,因為NaN 不等於任何內容,甚至不等於其本身。儘管如此,這兩個運算會產生相同的結果;如果使用2*x
來取代x x
,程式行為將是相同的,反之亦然。)