我正在用JavaScript編寫輸入範圍組件,該組件使用整數定義max
,min
和step
值。在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)}`);
}
如果您只需要返回給用戶,即他們提供的原始步驟值,爲什麼不只是存儲原始輸入的步驟值,然後稍後將其返回給他們,而不用擔心將其轉換爲整數,然後返回到小數? –
我可能不夠清楚,我使用範圍句柄返回用戶輸入的值,因此它由我的組件計算。我更新了這個問題來說明這一點。 –