2012-04-27 70 views
2

我在JavaScript中創建了數字微調控件,實質上模仿了webkit中的數字字段。JavaScript中的精確浮點運算

當您更改號碼,就需要檢查,看看是否值不僅是可接受的範圍之內,而且,它的步驟:

<input type="number" min="0" max="100" step="1" /> 

如果用戶輸入5.5領域將截斷這到最接近的步驟低於值,在這種情況下是5

對於2的步驟,如果用戶輸入5.5,結果將是4

我打算用這個計算公式是這樣的:

...code... 
_checkStep: function (val) { 
    val ret, 
     diff, 
     moddedDiff; 
    diff = val - this._min; 
    moddedDiff = diff % this._step; 
    ret = val - moddedDiff; 
    return ret; 
}, 
//set elsewhere 
_min, 
_step, 
...more code... 

雖然出於測試目的,你可以簡單地使用:

function checkStep(val, min, step) { 
    var ret, 
     diff, 
     moddedDiff; 
    diff = val - min; 
    moddedDiff = diff % step; 
    ret = val - moddedDiff; 
    return ret; 
} 

這對於整數和更大的偉大工程值,但是由於JavaScript如何處理浮點數,我遇到了小數點問題。

例如:

checkStep(0.5, 0, 0.1) //returns 0.4, 0.5 is expected 

在分析每行,事實證明,0.5 % 0.1在JavaScript返回0.09999999999999998

可以做些什麼來使這個功能更準確*?


*準確地說,它適用於增量爲0.01或更高。

+4

有沒有這樣的事情「正確」浮點。它們總是盡力而爲的近似值。您至多可以指定您願意接受的精度級別。 – 2012-04-27 16:13:40

+0

@MarcB,好點,忘了提到我有興趣把這項工作放到百分之一的地方。 – zzzzBov 2012-04-27 16:15:31

+2

*「JavaScript中的0.5%0.1返回0.09999999999999998」。*哦,這只是冰山一角。 '0.1 + 0.2 = 0.30000000000000004'。 – 2012-04-27 16:15:45

回答

-1

沒有絕對保證準確的浮點計算。改用整數計算。在你的0.1例子中,你可以用整數計算「0.1」的數量,直觀地在用戶的最後一位之前添加點。

+1

有趣的是,你說精度無法保證,因爲浮點運算的定義很明確,並且在每個瀏覽器中都會產生相同的結果。問題在於它往往違反直覺。我真的希望得到幫助,使浮點算術代碼更具彈性,並使其適用於合理的人類範圍。 – zzzzBov 2012-04-27 16:21:27

+0

嗯,我的意思是「從人類小數角度來看」的準確性,是的。 :)當然,它每次都會以完全相同的方式運行。 – 2012-04-27 16:23:06

1

您可以嘗試確保step大於1(通過反覆乘以10),然後進行模數計算,然後縮小到原始數值。例如:

function checkStep(val, min, step) { 
    var ret, 
    diff, 
    moddedDiff; 
    var pows = 0; 
    while(step < 1) { // make sure step is > 1 
    step *= 10; 
    val *= 10; 
    min *= 10; 
    pows++; 
    } 
    diff = val - min; 
    moddedDiff = diff % step; 
    ret = val - moddedDiff; 
    return ret/Math.pow(10, pows); 
} 

這適用於您提供的示例,但我無法保證它適用於所有內容。看到這裏的的jsfiddle:

http://jsfiddle.net/bCTL6/2/

+0

我打算用一些更新的代碼更新我的答案。我基本上做同樣的事情,但使用遞歸函數調用。它似乎工作到目前爲止,雖然有一些模數檢查也需要完成。 – zzzzBov 2012-04-27 21:34:12