2017-06-12 15 views
0

我正在用JavaScript編寫輸入範圍組件,該組件使用整數定義max,minstep值。在JavaScript中處理21位十進制數

如果用戶提供十進制step值,組件將使用此功能來獲得的小數位數,並將其轉換爲一個整數:

export function getDecimals(num) { 
    const stepArr = num.toString().split('.'); 
    return stepArr[1] ? stepArr[1].length : 0; 
} 

這樣做,該組件可以與整數工作,當需要將用戶插入的值(使用範圍句柄)返回給用戶時,它會將數字轉換回十進制數並將小數點設置爲step所提供的相同數量:

parseFloat(
    newValue.toFixed(getDecimals(this.props.step)) 
); 

this.props.step是由組件的消費者提供的原始值step

它工作得很好,但我收到其中消費者的一個接收RangeError因爲提供step號碼是一個bug報告:

0.000020735346383538284 

這個數字有21個十進制數字,而Number.toFixed支持不超過20位十進制數字。

這裏有一個攝製:

const step = 0.000020735346383538284; 
 

 
function getDecimals(num) { 
 
    const stepArr = num.toString().split('.'); 
 
    return stepArr[1] ? stepArr[1].length : 0; 
 
} 
 

 
function toSafe(num) { 
 
    return parseFloat(num.toFixed(getDecimals(step))); 
 
} 
 

 
console.log(toSafe(10));

我可以很容易地解決這個問題:

export function getDecimals(num) { 
    const stepArr = num.toString().split('.'); 
    return Math.min(20, stepArr[1] ? stepArr[1].length : 0); 
} 

但在這種情況下,我會失去由step值所需的精度,因爲我永遠不會返回超過20位十進制數字的值。

我該如何處理這種情況以保持精度?

更新

將這項功能的工作,或者它會搞砸,因爲字符串操作的一些數字?

export function toFixed(num, decimals) { 
    const parts = num.toString().split('.'); 
    return Number(`${parts[0]}.${(parts[1] || '').slice(0, decimals)}`); 
} 
+0

如果您只需要返回給用戶,即他們提供的原始步驟值,爲什麼不只是存儲原始輸入的步驟值,然後稍後將其返回給他們,而不用擔心將其轉換爲整數,然後返回到小數? –

+0

我可能不夠清楚,我使用範圍句柄返回用戶輸入的值,因此它由我的組件計算。我更新了這個問題來說明這一點。 –

回答

0

一個簡單的猜測就是使用某種大號碼庫。像this

+2

這應該是一條評論。 –

+0

請添加它作爲評論。 –

+0

我想避免導入整個庫來處理這個不太常見的邊界案例。 –