[英]Handle 21 decimals number in JavaScript
I'm writing an input range component in JavaScript, the component works with integers to define max
, min
and step
values. 我正在用JavaScript编写输入范围组件,该组件与整数一起使用以定义
max
, min
和step
值。
If the user provides a decimal step
value, the component will use this function to get the number of decimals and transform it to an integer: 如果用户提供了十进制
step
值,则组件将使用此函数获取小数位数并将其转换为整数:
export function getDecimals(num) {
const stepArr = num.toString().split('.');
return stepArr[1] ? stepArr[1].length : 0;
}
Doing so, the component can work with integers, and when it needs to return to the user the value inserted by the user (using the range handle), it will convert the number back to a decimal number and set the decimals to the same amount provided by step
with this function: 这样做,该组件可以使用整数,并且当需要将用户插入的值(使用范围句柄)返回给用户时,它将把数字转换回十进制数并将十进制数设置为相同的数量分
step
提供此功能:
parseFloat(
newValue.toFixed(getDecimals(this.props.step))
);
this.props.step
is the original step
value provided by the consumer of the component. this.props.step
是组件使用者提供的原始step
值。
It works pretty well, but I received a bug report where one of the consumers receives a RangeError
because the provided step
number is: 它工作得很好,但是我收到一个错误报告,其中一个使用者收到了
RangeError
因为提供的step
号是:
0.000020735346383538284
This number has 21 decimal digits, while Number.toFixed
supports no more than 20 decimal digits. 该数字具有21个十进制数字,而
Number.toFixed
支持不超过20个十进制数字。
Here's a repro: 这是一个复制品:
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));
I could easily fix this with: 我可以使用以下方法轻松解决此问题:
export function getDecimals(num) {
const stepArr = num.toString().split('.');
return Math.min(20, stepArr[1] ? stepArr[1].length : 0);
}
But in this case I'd lose the precision required by the step
value, because I would never return a value with more than 20 decimal digits. 但是在这种情况下,我将失去
step
值所需的精度,因为我永远不会返回超过20个十进制数字的值。
How could I handle this case to preserve the precision? 如何处理这种情况以保持精度?
update : 更新 :
Would this function work or is it going to mess up some numbers because of the string manipulation? 此功能将起作用还是由于字符串操作而使一些数字混乱?
export function toFixed(num, decimals) {
const parts = num.toString().split('.');
return Number(`${parts[0]}.${(parts[1] || '').slice(0, decimals)}`);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.