Existe uma maneira confiável no JavaScript de obter o número de casas decimais de um número arbitrári
É importante observar que não estou procurando uma função de arredondamento. Estou procurando uma função que retorna o número de casas decimais na representação decimal simplificada de um número arbitrário. Ou seja, temos o seguinte:
decimalPlaces(5555.0); //=> 0
decimalPlaces(5555); //=> 0
decimalPlaces(555.5); //=> 1
decimalPlaces(555.50); //=> 1
decimalPlaces(0.0000005); //=> 7
decimalPlaces(5e-7); //=> 7
decimalPlaces(0.00000055); //=> 8
decimalPlaces(5.5e-7); //=> 8
Meu primeiro instinto foi usar as representações de string: dividir em'.'
, em seguida'e-'
e faça as contas da seguinte maneira (o exemplo é detalhado):
function decimalPlaces(number) {
var parts = number.toString().split('.', 2),
integerPart = parts[0],
decimalPart = parts[1],
exponentPart;
if (integerPart.charAt(0) === '-') {
integerPart = integerPart.substring(1);
}
if (decimalPart !== undefined) {
parts = decimalPart.split('e-', 2);
decimalPart = parts[0];
}
else {
parts = integerPart.split('e-', 2);
integerPart = parts[0];
}
exponentPart = parts[1];
if (exponentPart !== undefined) {
return integerPart.length +
(decimalPart !== undefined ? decimalPart.length : 0) - 1 +
parseInt(exponentPart);
}
else {
return decimalPart !== undefined ? decimalPart.length : 0;
}
}
Para os meus exemplos acima, esta função funciona. No entanto, não estou satisfeito até ter testado todos os valores possíveis; por isso, perdiNumber.MIN_VALUE
.
Number.MIN_VALUE; //=> 5e-324
decimalPlaces(Number.MIN_VALUE); //=> 324
Number.MIN_VALUE * 100; //=> 4.94e-322
decimalPlaces(Number.MIN_VALUE * 100); //=> 324
Isso parecia razoável no começo, mas, em uma segunda análise, percebi que5e-324 * 10
deveria estar5e-323
! E então me ocorreu: estou lidando com os efeitos da quantização de números muito pequenos. Não são apenas os números quantificados antes do armazenamento; Além disso, alguns números armazenados em binários têm representações decimais irracionalmente longas, portanto, suas representações decimais estão sendo truncadas. Isso é lamentável para mim, porque significa que não consigo obter a precisão decimal verdadeira usando suas representações de string.
Então, eu venho até você, comunidade StackOverflow. Alguém de vocês conhece uma maneira confiável de obter a verdadeira precisão pós-decimal de um número?
O objetivo desta função, se alguém perguntar, é para uso em outra função que converte um float em uma fração simplificada (ou seja, retorna o numerador inteiro relativamente coprime e o denominador natural diferente de zero). A única peça que falta nessa função externa é uma maneira confiável de determinar o número de casas decimais no flutuador para que eu possa multiplicá-lo pela potência apropriada de 10. Espero que eu esteja exagerand